Як генерувати унікальний ідентифікатор за допомогою 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 Барад

Відповіді:


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 років і не перевіряв це, але основна ідея повинна дотримуватися - не використовувати зайнятий цикл та використовувати зворотні дзвінки. Можливо, ви захочете ознайомитись з пакетом асинхронного вузла.


4
Math.random - це поганий вибір, коли потрібен справді випадковий ідентифікатор, особливо якщо він повинен бути непередбачуваним / криптографічно захищеним.
Єчо Єков

326

Встановіть пакет NPU 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' 

дякую, але мені потрібно це зробити із запитом до бази даних. :)
сова

@owl Я не розумію, що ти маєш на увазі. У SQL?
Vinz243

51
Яка різниця, якщо вона знаходиться в db-запиті? У вас є унікальний ідентифікатор, тепер використовуйте його в тому інтерфейсі, який ви використовуєте для спілкування зі своєю базою даних.
jraede

Будь-яка ідея, в чому різниця між пакетами uuid і node-uuid?
ishandutta2007

5
@ ishandutta2007 node-uuid застаріло: "ВИЗНАЧЕНО: Замість цього використовуйте пакет uuid."
дітсу

237

Найшвидший спосіб створити в Node випадкову 32-знакову рядок - за допомогою власного cryptoмодуля:

const crypto = require("crypto");

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

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

53
Мені подобається це рішення, оскільки зовнішня залежність не потрібна. Також я знайшов, що версія base64 також є корисною. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
hiroshi

5
Це випадково чи унікально? Будь ласка, розробимо випадкову функцію.
Максимі

"Створює криптографічно сильні псевдовипадкові дані." API
Станісладрг відновить Моніку

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
Це спричиняє попередження про депресію.
Razze

34

Інший підхід - використання шортида пакету від npm.

Це дуже просто у використанні:

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

і має деякі переконливі особливості:

ShortId створює надзвичайно короткі непослідовні унікальні URL-адреси. Ідеально підходить для скорочення URL-адрес, ідентифікаторів MongoDB та Redis та будь-яких інших користувачів ідентифікаторів.

  • За замовчуванням 7-14 символів, сприятливих до URL: AZ, az, 0-9, _-
  • Непослідовні, тому вони не передбачувані.
  • Може генерувати будь-яку кількість ідентифікаторів без дублікатів, навіть мільйони на день.
  • Програми можна перезапустити будь-яку кількість разів без шансів повторити ідентифікатор.

"Програми можна перезапустити будь-яку кількість разів без шансу повторити ідентифікатор." Ви можете мені показати, як працює шортка?
Темно-полум'я

@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-посилання


19

Простий, заснований на часі, без залежностей:

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

Вихід: jzlatihl


плюс випадкове число (завдяки відповіді @Yaroslav Gaponov)

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

Вихідні дані jzlavejjperpituute


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) }
Yi Xiang Chong

3

Якщо комусь потрібен криптографічний UUID-сильний, для цього також є рішення.

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

npm install generate-safe-id

Чому б не UUID?

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

Ця бібліотека генерує 240-бітові ідентифікатори за допомогою крипто-RNG Node.js, припускаючи, що перший дублікат виникне після генерації 2 ^ 120 ідентифікаторів. Виходячи з поточного виробництва енергії людського роду, цей поріг буде неможливо переступити в осяжному майбутньому.

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

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

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. І ця реалізація також повинна зменшити арифметичні переливи, оскільки жодні операції не виконуються. Крім того, він більш ефективний у пам'яті порівняно з рядком, оскільки десяткові дроби займають менше пам'яті, ніж рядки.

Я називаю це "Чонг-Дробовим-Унікальним 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))все ще дають однакову довжину
Yi Xiang Chong
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.