Cara menghasilkan ID unik dengan 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;
}

Bagaimana cara menetapkan nilai variabel dengan panggilan balik permintaan basis data? Bagaimana saya bisa melakukannya?


@JamesAllardice, saya perlu memahami bagaimana ini bisa dilakukan dengan permintaan basis data. Maaf terima kasih
burung hantu

1
Pertanyaan ini salah ditandai sebagai duplikat. Pertanyaan yang ditautkan menjawab bagaimana melakukannya dalam javascript generik; jawaban dengan nilai tertinggi dalam pertanyaan ini khusus untuk node.js.
Mike Post

5
Saya ingin menempelkan ini sebagai jawaban: var hexstring = crypto.randomBytes(16).toString("hex");diikuti olehvar guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
selbie

Ini adalah jawaban yang bagus dengan new mongo.ObjectID();dan secara manual stackoverflow.com/a/56106999/4701635
Paresh Barad

Jawaban:


18

Sudah lama sejak saya menggunakan node.js, tapi saya pikir saya mungkin bisa membantu.

Pertama, dalam simpul, Anda hanya memiliki utas tunggal dan seharusnya menggunakan panggilan balik. Apa yang akan terjadi dengan kode Anda, adalah bahwa base.getIDkueri akan mendapatkan antrian untuk dieksekusi, tetapi whileloop akan terus berjalan sebagai loop sibuk tanpa tujuan.

Anda harus dapat menyelesaikan masalah Anda dengan panggilan balik sebagai berikut:

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

Dan gunakan seperti itu

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

Saya belum mengkodekan simpul / js dalam sekitar 2 tahun dan belum menguji ini, tetapi ide dasarnya harus terus - jangan menggunakan loop sibuk, dan gunakan callback. Anda mungkin ingin melihat pada paket async node.


4
Math.random adalah pilihan yang buruk ketika ID yang benar-benar acak diperlukan, terutama jika itu harus tidak dapat diprediksi / aman secara kriptografis.
Jecho Jekov

326

Instal paket NPM uuid (sumber: https://github.com/kelektiv/node-uuid ):

npm install uuid

dan gunakan dalam kode Anda:

var uuid = require('uuid');

Kemudian buat beberapa id ...

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

** PEMBARUAN 3.1.0
Penggunaan di atas sudah usang , jadi gunakan paket ini seperti ini:

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

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

** PEMBARUAN 7.x
Dan sekarang penggunaan di atas juga sudah usang , jadi gunakan paket ini seperti ini:

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

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

terima kasih, tapi saya perlu melakukannya dengan permintaan basis data. :)
owl

@ Oh, saya tidak mengerti maksud Anda. Dalam SQL?
Vinz243

51
Apa bedanya jika ada dalam permintaan db? Anda memiliki id unik, sekarang gunakan di antarmuka mana pun yang Anda gunakan untuk berkomunikasi dengan databse Anda.
Jraede

Adakah yang tahu perbedaan antara paket uuid dan node-uuid?
ishandutta2007

5
@ ishandutta2007 node-uuid tidak digunakan lagi: "TERGANGGU: Gunakan paket uuid sebagai gantinya."
diutsu

237

Cara tercepat yang mungkin untuk membuat string 32-char acak di Node adalah dengan menggunakan cryptomodul asli :

const crypto = require("crypto");

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

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

53
Saya suka solusi ini karena tidak ada ketergantungan eksternal yang diperlukan. Saya juga menemukan versi base64 juga bermanfaat. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
hiroshi

5
Apakah ini acak atau unik? Tolong jelaskan fungsi acak.
Maximi

'Menghasilkan data pseudo-acak yang kuat secara kriptografis.' API
Stanislasdrg Reinstate Monica

1
cryptosekarang dibangun ke dalam node itu sendiri .. Anda mendapatkan peringatan ini jika Anda menginstalnya 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
Ini sekarang menyebabkan peringatan penghentian.
Razze

34

Pendekatan lain adalah dengan menggunakan shortid paket dari NPM.

Sangat mudah digunakan:

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

dan memiliki beberapa fitur menarik:

ShortId membuat id unik unik yang ramah url dan tidak berurutan. Sempurna untuk penyingkat URL, ID MongoDB dan Redis, dan pengguna id lain mungkin melihat.

  • Secara default 7-14 karakter ramah-url: AZ, az, 0-9, _-
  • Tidak berurutan sehingga tidak dapat diprediksi.
  • Dapat menghasilkan jumlah id tanpa duplikat, bahkan jutaan per hari.
  • Aplikasi dapat dimulai ulang beberapa kali tanpa ada peluang untuk mengulangi id.

"Aplikasi dapat dinyalakan ulang beberapa kali tanpa ada peluang mengulangi id.?" Bisakah Anda menunjukkan kepada saya bagaimana shortid bekerja?
Navy Flame

@NavyFlame Ini dia: github.com/dylang/shortid atau lebih khusus github.com/dylang/shortid/issues/95
str

21

node-uuid sudah usang jadi silakan gunakan 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' 

Tautan npm


19

Sederhana, berbasis waktu, tanpa ketergantungan:

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

Keluaran: jzlatihl


ditambah nomor acak (Terima kasih atas jawaban @Yaroslav Gaponov)

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

Keluaran jzlavejjperpituute


9

Lebih mudah dan tanpa modul tambahan

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

2
Saya pikir itu tergantung pada panjangnya. sehingga Anda dapat memperluas kode ini seperti inline inifunction 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 adalah pilihan yang buruk ketika ID yang benar-benar acak diperlukan, terutama jika itu harus tidak dapat diprediksi / aman secara kriptografis.
Jecho Jekov

1
Ini tidak akan menghasilkan id unik yang benar-benar universal.
vicg

@JechoJekov "benar-benar acak"? Saya ragu
JDrake

Ya YaroslavGaponov bisa jadi benar karena kemungkinan pecahannya sama di ruang nyata [0, 1] adalah 0. Menulis kode untuk menghasilkan 1.000.000 Math.random () dan tidak dapat menemukan duplikat. 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

Jika seseorang membutuhkan UUID yang kuat kriptografis, ada solusi untuk itu juga.

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

npm install generate-safe-id

Mengapa tidak UUID?

UUID acak (UUIDv4) tidak memiliki cukup entropi untuk menjadi unik secara universal (ironis, eh?). UUID acak hanya memiliki 122 bit entropi, yang menunjukkan bahwa duplikat akan terjadi setelah hanya 2 ^ 61 ID. Selain itu, beberapa implementasi UUIDv4 tidak menggunakan generator nomor acak kriptografis yang kuat.

Pustaka ini menghasilkan ID 240-bit menggunakan Node.js crypto RNG, menunjukkan duplikat pertama akan terjadi setelah menghasilkan 2 ^ 120 ID. Berdasarkan produksi energi umat manusia saat ini, ambang batas ini tidak mungkin dilintasi untuk masa mendatang.

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

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

9
Ini adalah jawaban yang mungkin tidak lagi berfungsi untuk pengguna karena generate-safe-idditinggalkan dan kerentanan keamanan tidak diperbaiki (per Agustus 2018)
dannypaz

1

Saya menggunakan yang berikut ini dan berfungsi dengan baik plus tanpa ketergantungan pihak ketiga.

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

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


1

digunakan https://www.npmjs.com/package/uniqid dalam npm

npm i uniqid

Itu akan selalu membuat id unik berdasarkan waktu saat ini, proses dan nama mesin.

  • Dengan waktu saat ini, ID selalu unik dalam satu proses.
  • Dengan ID Proses ID unik meskipun dipanggil pada saat yang sama dari beberapa proses.
  • Dengan Alamat MAC, ID-nya unik meskipun dipanggil secara bersamaan dari beberapa mesin dan proses.

Fitur:-

  • Sangat cepat
  • Menghasilkan id unik di beberapa proses dan mesin meskipun dipanggil secara bersamaan.
  • Versi 8 dan 12 byte yang lebih pendek dengan lebih sedikit keunikan.

1

untuk menginstal uuid

npm install --save uuid

uuid diperbarui dan impor yang lama

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

tidak berfungsi dan kita sekarang harus menggunakan impor ini

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

dan untuk menggunakannya gunakan sebagai fungsi seperti ini =>

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

0

Memperluas dari jawaban YaroslavGaponov , implementasi paling sederhana hanya menggunakan Math.random().

Math.random()

Peluang pecahan sama dalam ruang nyata [0, 1] secara teoritis 0 dan mendekati 0 untuk panjang default 16 desimal di node.js. Dan implementasi ini juga harus mengurangi kelebihan aritmatika karena tidak ada operasi yang dilakukan. Selain itu, memori ini lebih efisien dibandingkan dengan string karena Desimal menempati lebih sedikit memori daripada string.

Saya menyebutnya "Chong-Fractional-Unique-ID" . Saya masih belum menulis makalah tentang sifat-sifatnya yang mudah-mudahan saya akan segera melakukannya.

Menulis kode untuk menghasilkan 1.000.000 Math.random()angka dan tidak dapat menemukan duplikat (setidaknya untuk titik desimal default 16). Lihat kode di bawah ini (berikan umpan balik jika ada):

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
} 

Juga, itu tergantung pada jumlah desimal. Saya menemukan bahwa di atas 13 desimal random_numbers.push(Math.random().toFixed(13))masih memberikan panjang yang sama
Yi Xiang Chong
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.