วิธีสร้าง ID เฉพาะด้วย 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
คำถามนี้ถูกตั้งค่าสถานะว่าซ้ำอย่างไม่ถูกต้อง คำถามที่เชื่อมโยงตอบคำถามวิธีการทำในจาวาสคริปต์ทั่วไป; คำตอบที่ได้คะแนนสูงสุดในคำถามนี้เฉพาะกับ node.js
Mike Post

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 ปีและยังไม่ได้ทดสอบสิ่งนี้ แต่แนวคิดพื้นฐานควรจะเก็บไว้ - อย่าใช้วนรอบที่ยุ่งและใช้การเรียกกลับ คุณอาจต้องการดูแพ็คเกจ async ของโหนด


4
Math.random เป็นตัวเลือกที่ไม่ดีเมื่อจำเป็นต้องใช้รหัสสุ่มโดยเฉพาะอย่างยิ่งหากจำเป็นต้องมีความปลอดภัยที่คาดเดาไม่ได้ / การเข้ารหัสลับ
Jecho Jekov

327

ติดตั้งแพ็คเกจ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'

** UPDATE 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 คุณมี ID ที่ไม่ซ้ำกันตอนนี้ใช้มันในอินเตอร์เฟสใดก็ตามที่คุณใช้เพื่อสื่อสารกับฐานข้อมูลของคุณ
jraede

ความคิดใดที่มีความแตกต่างระหว่างแพ็คเกจ uuid และ node-uuid
ishandutta2007

5
@ ishandutta2007 node-uuid ถูกคัดค้าน: "เลิกใช้แล้ว: ใช้แพ็คเกจ uuid แทน"
diutsu

237

วิธีที่เป็นไปได้ที่เร็วที่สุดในการสร้างสตริงแบบ 32 อักขระในโหนดคือการใช้cryptoโมดูลเนทีฟ:

const crypto = require("crypto");

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

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

53
ฉันชอบวิธีนี้เพราะไม่จำเป็นต้องพึ่งพาภายนอก ฉันก็พบว่า base64 version ก็มีประโยชน์เช่นกัน crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
ฮิโรชิ

5
มันสุ่มหรือไม่ซ้ำกัน? โปรดอธิบายฟังก์ชั่นการสุ่มอย่างละเอียด
Maximi

'สร้างข้อมูลสุ่มหลอกแบบเข้ารหัสลับที่แข็งแกร่ง' API
Stanislasdrg Reinstate Monica

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

อีกวิธีหนึ่งคือการใช้shortidแพคเกจจาก NPM

มันใช้งานง่ายมาก:

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

และมีคุณสมบัติที่น่าสนใจ:

ShortId สร้างรหัสประจำตัวที่ไม่ซ้ำใครต่อ URL ที่เป็นมิตรต่อ URL สมบูรณ์แบบสำหรับตัวย่อ URL, MongoDB และรหัส Redis และผู้ใช้รหัสอื่น ๆ อาจเห็น

  • ตามค่าเริ่มต้นอักขระ 7-14 URL ที่เป็นมิตร: AZ, az, 0-9, _-
  • ไม่ต่อเนื่องดังนั้นจึงไม่สามารถคาดเดาได้
  • สามารถสร้างรหัสจำนวนเท่าใดก็ได้โดยไม่ซ้ำซ้อนแม้กระทั่งล้านต่อวัน
  • แอพสามารถเริ่มต้นใหม่ได้หลายครั้งโดยไม่ต้องมี ID ซ้ำ

"แอปสามารถเริ่มใหม่ได้หลายครั้งโดยไม่ต้องมีรหัสซ้ำ" คุณช่วยแสดงให้ฉันเห็นว่า shortid ทำงานอย่างไร
Navy Flame

@NavyFlame นี่คุณไป: github.com/dylang/shortidหรือมากขึ้นโดยเฉพาะgithub.com/dylang/shortid/issues/95
STR

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'));
Yaroslav Gaponov

6
Math.random เป็นตัวเลือกที่ไม่ดีเมื่อจำเป็นต้องใช้รหัสสุ่มโดยเฉพาะอย่างยิ่งหากจำเป็นต้องมีความปลอดภัยที่คาดเดาไม่ได้ / การเข้ารหัสลับ
Jecho Jekov

1
สิ่งนี้จะไม่สร้างรหัสประจำตัวที่เป็นสากลอย่างแท้จริง
vicg

@JechoJekov "สุ่มอย่างแท้จริง"? ฉันสงสัย
JDrake

ใช่YaroslavGaponovอาจจะถูกต้องเนื่องจากโอกาสที่เศษส่วนจะเท่ากันในพื้นที่จริง [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

ทำไมไม่ UUIDs

UUIDs แบบสุ่ม (UUIDv4) มีเอนโทรปีไม่มากพอที่จะไม่ซ้ำกันในระดับสากล (แดกดัน, เอ๊ะ?) UUID แบบสุ่มมีเอนโทรปี122 บิตเท่านั้นซึ่งแสดงให้เห็นว่าซ้ำจะเกิดขึ้นหลังจากID 2 ^ 61เท่านั้น นอกจากนี้การใช้งาน UUIDv4 บางอย่างไม่ได้ใช้ตัวสร้างตัวเลขสุ่มแบบเข้ารหัสลับ

ไลบรารีนี้สร้างID 240 บิตโดยใช้ Node.js crypto RNG การแนะนำการทำซ้ำครั้งแรกจะเกิดขึ้นหลังจากสร้าง2 ^ 120 ID ขึ้นอยู่กับการผลิตพลังงานในปัจจุบันของเผ่าพันธุ์มนุษย์เกณฑ์นี้จะเป็นไปไม่ได้ที่จะข้ามไปในอนาคตอันใกล้

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

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

9
คำตอบนี้อาจไม่ทำงานสำหรับผู้ใช้อีกต่อไปเนื่องจากgenerate-safe-idถูกทอดทิ้งและช่องโหว่ด้านความปลอดภัยไม่ได้รับการแก้ไข (ณ เดือนสิงหาคม 2561)
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ในเวลา 17.00 น

npm i uniqid

มันจะสร้างรหัสที่ไม่ซ้ำกันตามเวลาปัจจุบันกระบวนการและชื่อเครื่อง

  • ด้วยเวลาปัจจุบันรหัสจะไม่ซ้ำกันในกระบวนการเดียวเสมอ
  • ด้วย ID กระบวนการรหัสจะไม่ซ้ำกันแม้ว่าจะถูกเรียกในเวลาเดียวกันจากหลายกระบวนการ
  • ด้วยที่อยู่ MAC รหัสจะไม่ซ้ำกันแม้ว่าจะถูกเรียกในเวลาเดียวกันจากหลายเครื่องและกระบวนการ

คุณสมบัติ: -

  • เร็วมาก
  • สร้าง id ที่ไม่ซ้ำกันในกระบวนการและเครื่องจักรที่หลากหลายแม้ว่าจะถูกเรียกในเวลาเดียวกัน
  • รุ่นที่สั้นกว่า 8 และ 12 ไบต์มีเอกลักษณ์น้อยลง

1

เพื่อติดตั้ง uuid

npm install --save uuid

uuid ได้รับการอัพเดตและการนำเข้าเก่า

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

ไม่ทำงานและเราควรใช้การนำเข้านี้

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

และสำหรับการใช้มันใช้เป็น funciton เช่นนี้ =>

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

0

ยื่นออกมาจากYaroslavGaponovMath.random()คำตอบของการดำเนินงานที่ง่ายที่สุดคือเพียงแค่ใช้

Math.random()

โอกาสที่เศษส่วนจะเท่ากันในพื้นที่จริง [0, 1] คือในทางทฤษฎี 0 และใกล้เคียงกับ 0 สำหรับความยาวเริ่มต้นที่ 16 ทศนิยมใน node.js และการใช้งานนี้ควรลดการโอเวอร์โฟลว์ทางคณิตศาสตร์ด้วยเนื่องจากไม่มีการดำเนินการใด ๆ นอกจากนี้หน่วยความจำยังมีประสิทธิภาพมากกว่าเมื่อเปรียบเทียบกับสตริงเนื่องจาก Decimals ใช้หน่วยความจำน้อยกว่าสตริง

ผมเรียกนี้"จงเศษส่วนที่ไม่ซ้ำ-ID" ฉันยังไม่ได้เขียนบทความเกี่ยวกับคุณสมบัติของมันซึ่งหวังว่าฉันจะไปถึงในไม่ช้า

เขียนโค้ดเพื่อสร้างMath.random()ตัวเลข1,000,000 และไม่สามารถหาข้อมูลซ้ำได้ (อย่างน้อยสำหรับจุดทศนิยมทศนิยมเริ่มต้นที่ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.