Node.js ile benzersiz kimlik oluşturma


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

Veritabanı sorgusu geri aramasıyla bir değişken değeri nasıl ayarlanır? Nasıl yapabilirim?


@JamesAllardice, bunun bir veritabanı sorgusu ile nasıl yapılabileceğini anlamam gerekiyor. Üzgünüm, teşekkürler.
baykuş

1
Bu soru yanlış bir kopya olarak işaretlenmiş. Bağlantılı soru, jenerik javascript'te nasıl yapılacağını cevaplar; bu sorudaki en yüksek oy alan cevap node.js'ye özgüdür.
Mike Post

5
Bunu bir cevap olarak yapıştırmak isterim: var hexstring = crypto.randomBytes(16).toString("hex");arkasındanvar guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
selbie

Bu new mongo.ObjectID();ve iyi bir cevaptır stackoverflow.com/a/56106999/4701635
Paresh Barad

Yanıtlar:


18

Node.js'yi kullandığımdan bu yana biraz zaman geçti, ama sanırım yardımcı olabilirim.

İlk olarak, düğümde, yalnızca tek bir iş parçacığınız vardır ve geri arama kullanmanız gerekir. Kodunuzda ne olacağı, base.getIDsorgunun yürütme için sıraya alınacağı, ancakwhile döngü sürekli olarak meşgul bir döngü olarak çalışacağıdır.

Sorununuzu geri arama ile aşağıdaki gibi çözebilmeniz gerekir:

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

Ve böyle kullanın

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

Yaklaşık 2 yıl içinde herhangi bir düğüm / js kodlamadım ve bunu test etmedim, ancak temel fikir tutmalı - meşgul bir döngü kullanmayın ve geri aramalar kullanmayın. Düğüm zaman uyumsuz paketine bir göz atmak isteyebilirsiniz.


4
Gerçekten rasgele bir kimlik gerektiğinde, özellikle öngörülemeyen / kriptografik olarak güvenli olması gerekiyorsa, Math.random kötü bir seçimdir.
Jecho Jekov

327

NPM uuid paketini yükleyin (kaynaklar: https://github.com/kelektiv/node-uuid ):

npm install uuid

ve kodunuzda kullanın:

var uuid = require('uuid');

Sonra bazı kimlikler oluşturun ...

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

** GÜNCELLEME 3.1.0
Yukarıdaki kullanım kullanımdan kaldırılmıştır , bu nedenle bu paketi şu şekilde kullanın:

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

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

** GÜNCELLEME 7.x
Ve şimdi yukarıdaki kullanım da kullanımdan kaldırıldı , bu yüzden bu paketi şu şekilde kullanın:

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

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

teşekkürler, ama bir veritabanı sorgusu ile yapmam gerekiyor. :)
baykuş

@owl Ne demek istediğini anlamıyorum. SQL'de mi?
Vinz243

51
Bir db sorgusunda ise ne fark eder? Benzersiz bir kimliğiniz var, şimdi veritabanınızla iletişim kurmak için hangi arabirimi kullanırsanız kullanın.
jraede

Uuid ve node-uuid paketleri arasındaki fark nedir?
ishandutta2007

5
@ ishandutta2007 node-uuid kullanımdan kaldırıldı: "DEPRECATED: Bunun yerine uuid paketini kullan."
diutsu

237

Düğümde rasgele 32 karakter dizesi oluşturmanın en hızlı yolu yerel cryptomodül kullanmaktır :

const crypto = require("crypto");

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

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

53
Bu çözümü seviyorum çünkü harici bir bağımlılığa gerek yok. Ayrıca base64 sürümünün de yararlı olduğunu gördüm. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
hiroshi

5
Rastgele mi yoksa benzersiz mi? Lütfen rastgele işlevi ayrıntılı olarak belirtin.
Maximi

'Kriptografik olarak güçlü sahte rastgele veriler üretir.' API
Stanislasdrg Eski Monica'yı

1
cryptoşimdi düğümün içine yerleştirilmiştir .. Eğer npm yüklerseniz bu uyarıyı alırsınız: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
Bu artık kullanımdan kaldırma uyarılarına neden oluyor.
Razze

34

Başka bir yaklaşım da npm'den kısa paketi kullanmaktır .

Kullanımı çok kolaydır:

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

ve bazı zorlayıcı özelliklere sahiptir:

ShortId inanılmaz derecede kısa sıralı olmayan url dostu benzersiz kimlikler oluşturur. URL kısaltıcıları, MongoDB ve Redis kimlikleri ve diğer kullanıcıların kimliğini görebileceği mükemmel.

  • Varsayılan olarak 7-14 URL dostu karakterler: AZ, az, 0-9, _-
  • Sıralı olmayan, bu nedenle tahmin edilemezler.
  • Günde milyonlarca, hatta kopya olmadan herhangi bir sayıda kimlik oluşturabilir.
  • Uygulamalar, bir kimliği tekrarlama şansı olmadan istediğiniz sayıda yeniden başlatılabilir.

"Uygulamalar bir kimliği tekrarlama şansı olmadan istediğiniz zaman yeniden başlatılabilir.?" Kısacanın nasıl çalıştığını gösterebilir misin?
Navy Flame

@NavyFlame İşte: github.com/dylang/shortid veya daha spesifik olarak github.com/dylang/shortid/issues/95
str

21

node-uuid kullanımdan kaldırıldı, lütfen kullanın 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 bağlantısı


19

Basit, zamana dayalı, bağımlılık olmadan:

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

Çıktı: jzlatihl


artı rastgele sayı (@Yaroslav Gaponov'un cevabı sayesinde)

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

Çıktı jzlavejjperpituute


9

Daha kolay ve ilave modülsüz

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

2
Bence uzunluğa bağlı. böylece bu kodu bu satır içi gibi genişletebilirsinizfunction 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
Gerçekten rasgele bir kimlik gerektiğinde, özellikle öngörülemeyen / kriptografik olarak güvenli olması gerekiyorsa, Math.random kötü bir seçimdir.
Jecho Jekov

1
Bu gerçekten evrensel olarak benzersiz bir kimlik oluşturmaz.
vicg

@JechoJekov "gerçekten rastgele"? Sanmam
JDrake

Evet YaroslavGaponov , kesirlerin gerçek bir alanda aynı olma şansı [0, 1] 0 olduğu için doğru olabilir. 1,000,000 Math.random () oluşturmak için kod yazdı ve herhangi bir kopya bulamadı. 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

Bazılarının kriptografik olarak güçlü UUID'ye ihtiyacı varsa, bunun için de bir çözüm var.

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

npm install generate-safe-id

Neden UUID'ler olmasın?

Rastgele UUID'ler (UUIDv4) evrensel olarak benzersiz olmak için yeterli entropiye sahip değildir (ironik, ha?). Rastgele UUID'lerde yalnızca 122 bit entropi vardır, bu da sadece 2 ^ 61 sonra bir yinelemenin gerçekleşeceğini gösterir ID'den . Ayrıca, bazı UUIDv4 uygulamaları kriptografik olarak güçlü bir rasgele sayı üreteci kullanmaz.

Bu kütüphane , Node.js kripto RNG'sini kullanarak 240 bitlik kimlikler oluşturur , bu da ilk yinelemenin 2 ^ 120 kimlikler oluşturulduktan sonra gerçekleşeceğini gösterir . İnsan ırkının mevcut enerji üretimine dayanarak, bu eşiğin öngörülebilir bir gelecek için geçilmesi imkansız olacaktır.

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

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

9
Bu yanıt, generate-safe-idterk
edilmeleri

1

Aşağıdaki kullanıyorum ve herhangi bir üçüncü taraf bağımlılığı olmadan iyi çalışıyor.

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

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


1

npm'de https://www.npmjs.com/package/uniqid kullanıldı

npm i uniqid

Her zaman geçerli zaman, işlem ve makine adına göre benzersiz kimlikler oluşturur.

  • Şimdiki zaman ile kimlikler tek bir işlemde her zaman benzersizdir.
  • İşlem Kimliği ile kimlikler, aynı anda birden çok işlemden çağrılsa bile benzersizdir.
  • MAC Adresi ile, aynı anda birden fazla makineden ve işlemden çağrılsa bile kimlikler benzersizdir.

Özellikleri:-

  • Çok hızlı
  • Aynı anda çağrılsa bile, birden çok işlemde ve makinede benzersiz kimlikler oluşturur.
  • Daha az benzersizliğe sahip daha kısa 8 ve 12 baytlık sürümler.

1

uuid kurmak

npm install --save uuid

uuid güncellenir ve eski içe aktarma

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

çalışmıyor ve şimdi bu içe aktarmayı kullanmalıyız

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

ve kullanmak için böyle bir funciton kullanın =>

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

0

Uzanan YaroslavGaponov 'ın cevabı, en basit uygulama sadece kullanıyor Math.random().

Math.random()

Kesirlerin gerçek bir boşlukta aynı olma olasılığı [0, 1], düğümde varsayılan olarak 16 ondalık uzunluk için teorik olarak 0 ve yaklaşık 0'a yakındır. Js. Ve bu uygulama, hiçbir işlem yapılmadığından aritmetik taşmaları da azaltmalıdır. Ayrıca, Ondalıklar dizelerden daha az bellek kapladığından bir dizeye kıyasla daha fazla bellek verimlidir.

Ben buna "Chong-Kesirli-Benzersiz-Kimlik" diyorum . Henüz özellikleri hakkında henüz bir makale yazmadım, umarım yakında alacağım.

1.000.000 Math.random()sayı üretmek için kod yazdı ve hiçbir kopya bulamadı (en az 16 varsayılan ondalık basamak için). Aşağıdaki koda bakın (lütfen varsa geri bildirim sağlayın):

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
} 

Ayrıca, ondalık sayılara da bağlıdır. Ben 13 ondalık onda random_numbers.push(Math.random().toFixed(13))hala aynı uzunluğu verdi bulundu
Yi Xiang Chong
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.