Как создать уникальный идентификатор с помощью 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;
}

Как установить значение переменной с обратным вызовом запроса базы данных? Как я могу это сделать?

сова
источник
@JamesAllardice, мне нужно понять, как это можно сделать с помощью запроса к базе данных. Извините спасибо
сова
1
Этот вопрос неправильно помечен как дубликат. Связанный вопрос отвечает, как сделать это в общем javascript; самый высокий рейтинг ответа на этот вопрос специфичен для node.js.
Майк Пост
5
Я хотел бы вставить это как ответ: 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);
selbie
Это хороший ответ с new mongo.ObjectID();помощью stackoverflow.com/a/56106999/4701635
Paresh Barad

Ответы:

18

Прошло некоторое время с тех пор, как я использовал node.js, но я думаю, что смогу помочь.

Во-первых, в узле у вас есть только один поток, и вы должны использовать обратные вызовы. Что произойдет с вашим кодом, так это то, что base.getIDзапрос будет поставлен в очередь для выполнения, но whileцикл будет непрерывно бессмысленно выполняться как занятый цикл.

Вы должны быть в состоянии решить вашу проблему с обратным вызовом следующим образом:

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

И использовать его как таковой

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

Я не кодировал ни одного узла / js в течение 2 лет и не проверял это, но основная идея должна сохраниться - не использовать занятый цикл и использовать обратные вызовы. Возможно, вы захотите взглянуть на асинхронный пакет узла.

rafalio
источник
4
Math.random - плохой выбор, когда нужен действительно случайный идентификатор, особенно если он должен быть непредсказуемым / криптографически безопасным.
Джечо Йеков
328

Установите пакет NPM uuid (источники: https://github.com/kelektiv/node-uuid ):

npm install uuid

и используйте его в своем коде:

var uuid = require('uuid');

Затем создайте несколько идентификаторов ...

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

** ОБНОВЛЕНИЕ 3.1.0
Вышеуказанное использование устарело , поэтому используйте этот пакет следующим образом:

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

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

** ОБНОВЛЕНИЕ 7.x
И теперь вышеупомянутое использование рекомендуется , так что используйте этот пакет следующим образом:

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

const { v4: uuidv4 } = require('uuid');
uuidv4(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 
Vinz243
источник
спасибо, но мне нужно сделать это с помощью запроса к базе данных. :)
сова
@ Я не понимаю, что ты имеешь в виду. В SQL?
Vinz243
51
Какая разница, если это в запросе БД? У вас есть уникальный идентификатор, теперь используйте его в любом интерфейсе, который вы используете для связи со своей базой данных.
Jraede
Есть идеи, в чем разница между пакетами uuid и node-uuid?
ishandutta2007
5
@ ishandutta2007 node-uuid устарел: «УСТАРЕЛО: используйте вместо этого пакет uuid».
17
237

Самый быстрый способ создать произвольную 32-символьную строку в Node - использовать встроенный cryptoмодуль:

const crypto = require("crypto");

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

console.log(id); // => f9b327e70bbcf42494ccb28b2d98e00e
Pono
источник
53
Мне нравится это решение, потому что никакой внешней зависимости не требуется. Также я обнаружил, что версия base64 тоже полезна. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
Хироши
5
Это случайно или уникально? Пожалуйста, разработайте случайную функцию.
Maximi
«Генерирует криптографически стойкие псевдослучайные данные». API
Stanislasdrg Восстановить Монику
1
cryptoтеперь встроен в сам узел. Вы получаете это предупреждение, если устанавливаете 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
AIon
1
Это теперь вызывает предупреждения об устаревании.
Раззе
34

Другой подход заключается в использовании пакета shorttid из npm.

Он очень прост в использовании:

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

и имеет некоторые неотразимые особенности:

ShortId создает удивительно короткие непоследовательные уникальные идентификаторы, дружественные по URL. Идеально подходит для сокращения URL-адресов, MongoDB и Redis ID, а также для любых других пользователей id.

  • По умолчанию 7-14 удобных для URL символов: AZ, az, 0-9, _-
  • Непоследовательные, поэтому они не предсказуемы.
  • Может генерировать любое количество идентификаторов без дубликатов, даже миллионы в день.
  • Приложения могут быть перезапущены любое количество раз без возможности повторения идентификатора.
ул
источник
«Приложения могут быть перезапущены любое количество раз без какой-либо возможности повторения идентификатора.?» Можете ли вы показать мне, как работает шортид?
Navy Flame
@NavyFlame Здесь вы идете: github.com/dylang/shortid или более конкретно github.com/dylang/shortid/issues/95
ул
21

node-uuid устарела, поэтому, пожалуйста, используйте 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

Praveena
источник
19

Простой, основанный на времени, без зависимостей:

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

Вывод: jzlatihl


плюс случайное число (спасибо ответу Ярослава Гапонова)

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

Вывод jzlavejjperpituute

safrazik
источник
9

Более простые и без дополнительных модулей

Math.random().toString(26).slice(2)
Ярослав Гапонов
источник
2
Я думаю, что это зависит от длины. так что вы можете расширить этот код следующим образомfunction getId(mask) { return mask.replace(/[x]/gi, () => { return Math.random().toString(26)[5]; }) } console.log(getId('xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'));
Ярослав Гапонов
6
Math.random - плохой выбор, когда нужен действительно случайный идентификатор, особенно если он должен быть непредсказуемым / криптографически безопасным.
Джечо Йеков
1
Это не будет генерировать действительно универсально уникальный идентификатор.
vicg
@JechoJekov "действительно случайно"? Я сомневаюсь в этом
JDrake
Да, Ярослав Гапонов может быть прав, поскольку вероятность того, что дроби будут одинаковыми в реальном пространстве [0, 1], равна 0. Написал код для генерации 1 000 000 Math.random () и не смог найти дубликатов. 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) }
И Сян Чонг
3

Если кому-то нужен криптографически сильный UUID, для этого также есть решение.

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

npm install generate-safe-id

Почему не UUID?

Случайные UUID (UUIDv4) не обладают достаточной энтропией, чтобы быть универсально уникальными (иронично, а?). Случайные UUID имеют только 122 бита энтропии, что говорит о том, что дубликат будет возникать только после 2 ^ 61 идентификаторов. Кроме того, некоторые реализации UUIDv4 не используют криптографически сильный генератор случайных чисел.

Эта библиотека генерирует 240-битные идентификаторы с использованием крипто-ГСЧ Node.js, предполагая, что первый дубликат произойдет после генерации 2 ^ 120 идентификаторов. Исходя из текущего производства энергии человечеством, этот порог будет невозможно пересечь в обозримом будущем.

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

var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"
ch3ll0v3k
источник
9
Этот ответ может больше не работать для пользователей из-за того, generate-safe-idчто он был заброшен И уязвимости безопасности не исправлены (по состоянию на август 2018 года)
dannypaz
1

Я использую следующее, и это работает нормально плюс без каких-либо сторонних зависимостей.

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

const uid = Math.random().toString(36).slice(2) + randomBytes(8).toString('hex') + new Date().getTime();
Пашам Ахил Кумар Редди
источник
1

использовал https://www.npmjs.com/package/uniqid в npm

npm i uniqid

Он всегда будет создавать уникальные идентификаторы на основе текущего времени, процесса и имени машины.

  • С текущим временем идентификаторы всегда уникальны в одном процессе.
  • С идентификатором процесса идентификаторы уникальны, даже если они вызываются одновременно из нескольких процессов.
  • С MAC-адресом идентификаторы являются уникальными, даже если они вызываются одновременно из нескольких машин и процессов.

Характеристики:-

  • Очень быстро
  • Создает уникальные идентификаторы на нескольких процессах и машинах, даже если они вызваны одновременно.
  • Более короткие 8- и 12-байтовые версии с меньшей уникальностью.
Джаяни Сумудини
источник
1

установить uuid

npm install --save uuid

uuid обновлен и старый импорт

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

не работает, и теперь мы должны использовать этот импорт

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

и для его использования используйте как функцию =>

const  createdPlace = {
    id: uuid(),
    title,
    description,
    location:coordinates,
    address,
    creator
  };
Рохан Деваки
источник
0

Продолжая ответ Ярослава Гапонова, самая простая реализация - это просто использование Math.random().

Math.random()

Вероятность того, что дроби будут одинаковыми в реальном пространстве [0, 1], теоретически равна 0 и приблизительно равна 0 для длины по умолчанию 16 десятичных знаков в файле node.js. И эта реализация должна также уменьшить арифметические переполнения, поскольку никакие операции не выполняются. Кроме того, он эффективнее по сравнению со строкой, так как десятичные дроби занимают меньше памяти, чем строки.

Я называю это «Chong-Fractional-Unique-ID» . Я до сих пор не написал статью о его свойствах, которая, надеюсь, скоро появится.

Написал код для генерации 1 000 000 Math.random()чисел и не смог найти дубликатов (по крайней мере для десятичных точек по умолчанию 16). Смотрите код ниже (пожалуйста, оставьте отзыв, если есть):

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
} 
И Сян Чонг
источник
Кроме того, это зависит от количества десятичных знаков. Я обнаружил, что более 13 десятичных знаков по- random_numbers.push(Math.random().toFixed(13))прежнему дают одинаковую длину
И Сян Чонг