Cách tạo ID duy nhất với 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;
}

Làm cách nào để đặt giá trị biến với gọi lại truy vấn cơ sở dữ liệu? Tôi phải làm việc đó như thế nào?


@James ALLardice, tôi cần hiểu làm thế nào điều này có thể được thực hiện với một truy vấn cơ sở dữ liệu. Xin lỗi, cảm ơn.

1
Câu hỏi này được gắn cờ không chính xác là một bản sao. Câu hỏi được liên kết trả lời làm thế nào để làm điều đó trong javascript chung; câu trả lời được đánh giá cao nhất trong câu hỏi này là dành riêng cho node.js.
Mike Post

5
Tôi rất thích dán câu này như một câu trả lời: var hexstring = crypto.randomBytes(16).toString("hex");tiếp theo làvar guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
selbie

Đây là một câu trả lời tốt với new mongo.ObjectID();stackoverflow
công.com

Câu trả lời:


18

Đã được một thời gian kể từ khi tôi sử dụng node.js, nhưng tôi nghĩ rằng tôi có thể giúp đỡ.

Thứ nhất, trong nút, bạn chỉ có một luồng duy nhất và được cho là sử dụng các cuộc gọi lại. Điều gì sẽ xảy ra với mã của bạn, đó là base.getIDtruy vấn sẽ được xếp hàng để thực hiện, nhưng whilevòng lặp sẽ tiếp tục chạy như một vòng lặp bận rộn vô nghĩa.

Bạn sẽ có thể giải quyết vấn đề của mình bằng một cuộc gọi lại như sau:

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

Và sử dụng nó như vậy

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

Tôi đã không mã hóa bất kỳ nút / js nào trong khoảng 2 năm và chưa thử nghiệm điều này, nhưng ý tưởng cơ bản nên nắm giữ - không sử dụng vòng lặp bận rộn và sử dụng các cuộc gọi lại. Bạn có thể muốn xem gói async nút.


4
Math.random là một lựa chọn kém khi cần một ID thực sự ngẫu nhiên, đặc biệt nếu nó cần phải được dự đoán / bảo mật bằng mật mã.
Jecho Jekov

326

Cài đặt gói uMid NPM (nguồn: https://github.com/kelekunch/node-uuid ):

npm install uuid

và sử dụng nó trong mã của bạn:

var uuid = require('uuid');

Sau đó tạo một số 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'

** CẬP NHẬT 3.1.0
Việc sử dụng ở trên không được chấp nhận , vì vậy hãy sử dụng gói này như thế này:

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

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

** CẬP NHẬT 7.x
Và bây giờ việc sử dụng ở trên cũng không được chấp nhận , vì vậy hãy sử dụng gói này như thế này:

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

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

cảm ơn, nhưng tôi cần phải làm điều đó với một truy vấn cơ sở dữ liệu. :)

@owl Tôi không hiểu ý bạn. Trong SQL?
Vinz243

51
Nó có gì khác biệt nếu nó nằm trong truy vấn db? Bạn có một id duy nhất, bây giờ sử dụng nó trong bất kỳ giao diện nào bạn sử dụng để giao tiếp với cơ sở dữ liệu của bạn.
jraede

Có ai biết sự khác biệt giữa các gói uuid và node-uuid không?
ishandutta2007

5
@ ishandutta2007 node-uuid không được dùng nữa: "Thay thế: Sử dụng gói uuid thay thế."
diutsu

237

Cách nhanh nhất có thể để tạo chuỗi 32 char ngẫu nhiên trong Node là sử dụng cryptomô đun gốc :

const crypto = require("crypto");

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

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

53
Tôi thích giải pháp này vì không cần phụ thuộc bên ngoài. Ngoài ra tôi thấy phiên bản base64 cũng hữu dụng. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
hiroshi

5
Nó là ngẫu nhiên hay duy nhất? Hãy xây dựng chức năng ngẫu nhiên.
Maximi

'Tạo dữ liệu giả ngẫu nhiên mạnh về mật mã.' API
Stanislasdrg Tái lập Monica

1
cryptohiện được tích hợp vào nút .. Bạn nhận được cảnh báo này nếu bạn cài đặt nó: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
Điều này bây giờ gây ra cảnh báo khấu hao.
Razze

34

Một cách tiếp cận khác là sử dụng gói shortid từ npm.

Nó rất dễ sử dụng:

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

và có một số tính năng hấp dẫn:

ShortId tạo ra các id duy nhất không thân thiện với url không liên tục. Hoàn hảo cho các công cụ rút ngắn url, id MongoDB và Redis và bất kỳ người dùng id nào khác có thể thấy.

  • Theo mặc định 7-14 ký tự thân thiện với url: AZ, az, 0-9, _-
  • Không tuần tự nên chúng không thể dự đoán được.
  • Có thể tạo bất kỳ số lượng id nào mà không cần trùng lặp, thậm chí hàng triệu mỗi ngày.
  • Ứng dụng có thể được khởi động lại bất kỳ số lần nào mà không có cơ hội lặp lại id.

"Ứng dụng có thể được khởi động lại bất kỳ số lần nào mà không có cơ hội lặp lại id.?" Bạn có thể chỉ cho tôi cách làm việc ngắn hạn?
Ngọn lửa hải quân

@NeefFlame Ở đây bạn đi: github.com/dylang/shortid hoặc cụ thể hơn là github.com/dylang/shortid/issues/95
str

21

node-uuid không dùng nữa nên vui lòng sử dụng 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' 

Liên kết Npm


19

Đơn giản, dựa trên thời gian, không phụ thuộc:

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

Đầu ra: jzlatihl


cộng với số ngẫu nhiên (Cảm ơn câu trả lời của @Yaroslav Gaponov)

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

Đầu ra jzlavejjperpituute


9

Dễ dàng hơn và không có mô-đun bổ sung

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

2
Tôi nghĩ rằng nó phụ thuộc vào chiều dài. vì vậy bạn có thể mở rộng mã này như nội tuyến nàyfunction 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 là một lựa chọn kém khi cần một ID thực sự ngẫu nhiên, đặc biệt nếu nó cần phải được dự đoán / bảo mật bằng mật mã.
Jecho Jekov

1
Điều này sẽ không tạo ra một id thực sự phổ biến duy nhất.
cha mẹ

@JechoJekov "thực sự ngẫu nhiên"? Tôi nghi ngờ điều đó
JDrake

Có, YaroslavGaponov có thể đúng vì cơ hội của các phân số là như nhau trong một không gian thực [0, 1] là 0. Viết mã để tạo 1.000.000 Math.random () và không thể tìm thấy bất kỳ bản sao nào. 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

Nếu ai đó cần UUID mạnh về mật mã, thì cũng có giải pháp cho điều đó.

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

npm install generate-safe-id

Tại sao không phải là UUID?

Các UUID ngẫu nhiên (UUIDv4) không có đủ entropy để trở thành duy nhất trên toàn cầu (mỉa mai, eh?). Các UUID ngẫu nhiên chỉ có 122 bit entropy, điều này cho thấy rằng một bản sao sẽ xảy ra chỉ sau 2 ^ 61 ID. Ngoài ra, một số triển khai UUIDv4 không sử dụng trình tạo số ngẫu nhiên mạnh về mật mã.

Thư viện này tạo ID 240 bit bằng cách sử dụng Rode mật mã Node.js, cho thấy sự trùng lặp đầu tiên sẽ xảy ra sau khi tạo 2 ^ 120 ID. Dựa trên sản xuất năng lượng hiện tại của loài người, ngưỡng này sẽ không thể vượt qua trong tương lai gần.

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

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

9
Đây là câu trả lời có thể không còn hoạt động cho người dùng do generate-safe-idbị bỏ rơi VÀ các lỗ hổng bảo mật không được sửa chữa (kể từ tháng 8 năm 2018)
dannypaz

1

Tôi đang sử dụng những điều sau đây và nó đang hoạt động tốt cộng với không có sự phụ thuộc của bên thứ ba.

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

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


1

đã sử dụng https://www.npmjs.com/package/uniqid trong npm

npm i uniqid

Nó sẽ luôn tạo id duy nhất dựa trên thời gian, quy trình và tên máy hiện tại.

  • Với thời điểm hiện tại, ID luôn là duy nhất trong một quy trình.
  • Với ID tiến trình, ID là duy nhất ngay cả khi được gọi cùng lúc từ nhiều quy trình.
  • Với Địa chỉ MAC, ID là duy nhất ngay cả khi được gọi cùng lúc từ nhiều máy và quy trình.

Đặc trưng:-

  • Rất nhanh
  • Tạo id duy nhất trên nhiều quy trình và máy ngay cả khi được gọi cùng lúc.
  • Các phiên bản 8 và 12 byte ngắn hơn với ít tính độc đáo hơn.

1

để cài đặt uuid

npm install --save uuid

uuid được cập nhật và nhập khẩu cũ

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

không hoạt động và bây giờ chúng ta nên sử dụng nhập này

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

và để sử dụng nó, hãy sử dụng như một funciton như thế này =>

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

0

Mở rộng từ câu trả lời của YaroslavGaponov , cách thực hiện đơn giản nhất chỉ là sử dụng Math.random().

Math.random()

Cơ hội của các phân số là giống nhau trong một không gian thực [0, 1] về mặt lý thuyết là 0 và gần bằng 0 với độ dài mặc định là 16 số thập phân trong node.js. Và việc thực hiện này cũng sẽ làm giảm tràn số học vì không có thao tác nào được thực hiện. Ngoài ra, nó hiệu quả hơn về bộ nhớ so với một chuỗi vì Decimals chiếm ít bộ nhớ hơn chuỗi.

Tôi gọi nó là "Chong-Fractional-Unique-ID" . Tôi vẫn chưa viết một bài báo về các thuộc tính của nó và hy vọng tôi sẽ sớm nhận được nó.

Đã viết mã để tạo 1.000.000 Math.random()số và không thể tìm thấy bất kỳ bản sao nào (ít nhất là cho số thập phân mặc định là 16). Xem mã dưới đây (vui lòng cung cấp thông tin phản hồi nếu có):

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
} 

Ngoài ra, nó phụ thuộc vào số lượng thập phân. Tôi thấy rằng trên 13 số thập phân random_numbers.push(Math.random().toFixed(13))vẫn có cùng độ dài
Yi Xiang Chong
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.