Cómo generar una identificación única 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;
}

¿Cómo establecer un valor variable con devolución de llamada de consulta de base de datos? ¿Cómo puedo hacerlo?

búho
fuente
@JamesAllardice, necesito entender cómo se puede hacer esto con una consulta de base de datos. Lo siento gracias
búho
1
Esta pregunta está marcada incorrectamente como un duplicado. La pregunta vinculada responde cómo hacerlo en javascript genérico; la respuesta mejor calificada en esta pregunta es específica de node.js.
Mike Post
55
Me encantaría pegar esto como respuesta: var hexstring = crypto.randomBytes(16).toString("hex");seguido devar guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
selbie
Esta es una buena respuesta new mongo.ObjectID();y stackoverflow.com/a/56106999/4701635
Paresh Barad

Respuestas:

18

Ha pasado algún tiempo desde que usé node.js, pero creo que podría ayudarlo.

En primer lugar, en el nodo, solo tiene un solo subproceso y se supone que debe usar devoluciones de llamada. Lo que sucederá con su código es que la base.getIDconsulta se pondrá en cola para su ejecución, pero el whilebucle se ejecutará continuamente como un bucle ocupado sin sentido.

Debería poder resolver su problema con una devolución de llamada de la siguiente manera:

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

Y úsalo como tal

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

No he codificado ningún nodo / js en alrededor de 2 años y no lo he probado, pero la idea básica debería ser válida: no use un bucle ocupado y use devoluciones de llamada. Es posible que desee echar un vistazo al paquete asíncrono de nodo.

rafalio
fuente
44
Math.random es una mala elección cuando se necesita una identificación verdaderamente aleatoria, especialmente si necesita ser impredecible / criptográficamente segura.
Jecho Jekov
326

Instale el paquete uuid NPM (fuentes: https://github.com/kelektiv/node-uuid ):

npm install uuid

y úsalo en tu código:

var uuid = require('uuid');

Luego crea algunos identificadores ...

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

** ACTUALIZACIÓN 3.1.0
El uso anterior está en desuso , así que use este paquete así:

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

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

** ACTUALIZACIÓN 7.x
Y ahora el uso anterior también está en desuso , así que use este paquete así:

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

const { v4: uuidv4 } = require('uuid');
uuidv4(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 
Vinz243
fuente
gracias, pero necesito hacerlo con una consulta de base de datos. :)
búho
@owl No entiendo lo que quieres decir. En SQL?
Vinz243
51
¿Qué diferencia hay si está en una consulta db? Tiene una identificación única, ahora úsela en cualquier interfaz que use para comunicarse con su base de datos.
jraede
¿Alguna idea de cuál es la diferencia entre los paquetes uuid y node-uuid?
ishandutta2007
55
@ ishandutta2007 node-uuid está en desuso: "DEPRECATED: Use el paquete uuid en su lugar".
diutsu
237

La forma más rápida posible de crear una cadena aleatoria de 32 caracteres en Node es mediante el uso del cryptomódulo nativo :

const crypto = require("crypto");

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

console.log(id); // => f9b327e70bbcf42494ccb28b2d98e00e
Pono
fuente
53
Me gusta esta solución porque no se necesita dependencia externa. También encontré que la versión base64 también es útil. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
hiroshi el
55
¿Es aleatorio o único? Por favor elabore una función aleatoria.
Maximi
'Genera datos pseudoaleatorios criptográficamente fuertes'. API
Stanislasdrg Restablece a Monica
1
cryptoahora está integrado en el propio nodo. Recibirá esta advertencia si npm lo instala:[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
A
1
Esto ahora provoca advertencias de desaprobación.
Razze
34

Otro enfoque utiliza el ShortID paquete de NPM.

Es muy fácil de usar:

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

y tiene algunas características atractivas:

ShortId crea identificadores únicos, increíblemente cortos, no secuenciales y amigables con las URL. Perfecto para acortadores de URL, identificadores de MongoDB y Redis, y cualquier otro usuario de identificación que pueda ver.

  • Por defecto, 7-14 caracteres amigables para la URL: AZ, az, 0-9, _-
  • No secuenciales, por lo que no son predecibles.
  • Puede generar cualquier número de identificadores sin duplicados, incluso millones por día.
  • Las aplicaciones se pueden reiniciar varias veces sin posibilidad de repetir una identificación.
str
fuente
"Las aplicaciones se pueden reiniciar varias veces sin posibilidad de repetir una identificación". ¿Me puede mostrar cómo funciona shortid?
Navy Flame
@NavyFlame Aquí tienes: github.com/dylang/shortid o más específicamente github.com/dylang/shortid/issues/95
str
21

node-uuid está en desuso, así que por favor use 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' 

Enlace Npm

Praveena
fuente
19

Simple, basado en el tiempo, sin dependencias:

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

Salida: jzlatihl


más número aleatorio (Gracias a la respuesta de @Yaroslav Gaponov)

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

Salida jzlavejjperpituute

safrazik
fuente
9

Más fácil y sin módulos adicionales

Math.random().toString(26).slice(2)
Yaroslav Gaponov
fuente
2
Creo que depende de la longitud. para que pueda extender este código como este en líneafunction getId(mask) { return mask.replace(/[x]/gi, () => { return Math.random().toString(26)[5]; }) } console.log(getId('xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'));
Yaroslav Gaponov
66
Math.random es una mala elección cuando se necesita una identificación verdaderamente aleatoria, especialmente si necesita ser impredecible / criptográficamente segura.
Jecho Jekov
1
Esto no generará una identificación verdaderamente universalmente única.
vic
@JechoJekov "realmente al azar"? Lo dudo
JDrake
Sí, YaroslavGaponov podría ser correcto ya que las posibilidades de que las fracciones sean las mismas en un espacio real [0, 1] es 0. Escribió el código para generar 1,000,000 Math.random () y no pudo encontrar ningún duplicado. 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 alguien necesita un UUID criptográfico fuerte, también hay una solución para eso.

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

npm install generate-safe-id

¿Por qué no los UUID?

Los UUID aleatorios (UUIDv4) no tienen suficiente entropía para ser universalmente únicos (irónico, ¿eh?). Los UUID aleatorios tienen solo 122 bits de entropía, lo que sugiere que se producirá un duplicado después de solo 2 ^ 61 ID. Además, algunas implementaciones de UUIDv4 no utilizan un generador de números aleatorios criptográficamente fuerte.

Esta biblioteca genera ID de 240 bits utilizando el Node.js crypto RNG, lo que sugiere que el primer duplicado ocurrirá después de generar 2 ^ 120 ID. Basado en la producción actual de energía de la raza humana, este umbral será imposible de cruzar en el futuro previsible.

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

var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"
ch3ll0v3k
fuente
9
Es posible que esta respuesta ya no funcione para los usuarios debido al generate-safe-idabandono Y a que no se corrigieron las vulnerabilidades de seguridad (a partir de agosto de 2018)
dannypaz
1

Estoy usando lo siguiente y funciona bien y sin dependencias de terceros.

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

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

https://www.npmjs.com/package/uniqid usado en npm

npm i uniqid

Siempre creará identificaciones únicas basadas en la hora actual, el proceso y el nombre de la máquina.

  • Con la hora actual, los ID siempre son únicos en un solo proceso.
  • Con el ID de proceso, los ID son únicos incluso si se llaman al mismo tiempo desde múltiples procesos.
  • Con la dirección MAC, las ID son únicas incluso si se llaman al mismo tiempo desde múltiples máquinas y procesos.

Caracteristicas:-

  • Muy rapido
  • Genera identificaciones únicas en múltiples procesos y máquinas, incluso si se llama al mismo tiempo.
  • Versiones más cortas de 8 y 12 bytes con menos singularidad.
Jayani Sumudini
fuente
1

instalar uuid

npm install --save uuid

uuid se actualiza y la importación anterior

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

no funciona y ahora deberíamos usar esta importación

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

y para usarlo use como una función como esta =>

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

Extendiéndose de la respuesta de YaroslavGaponov , la implementación más simple es simplemente usar Math.random().

Math.random()

Las posibilidades de que las fracciones sean las mismas en un espacio real [0, 1] es teóricamente 0 y aproximadamente cercano a 0 para una longitud predeterminada de 16 decimales en node.js. Y esta implementación también debería reducir los desbordamientos aritméticos ya que no se realizan operaciones. Además, es más eficiente en la memoria en comparación con una cadena, ya que los decimales ocupan menos memoria que las cadenas.

Yo llamo a esto el "ID-Chong-Fractional-Unique" . Todavía no he escrito un documento sobre sus propiedades, que espero poder leer pronto.

Escribió un código para generar 1,000,000 de Math.random()números y no pudo encontrar ningún duplicado (al menos para los puntos decimales predeterminados de 16). Vea el código a continuación (proporcione comentarios si los hay):

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
fuente
Además, depende de la cantidad de decimales. Descubrí que más de 13 decimales random_numbers.push(Math.random().toFixed(13))todavía dan la misma duración
Yi Xiang Chong