node.jsで一意のIDを生成する方法


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);
セルビー

これは良い答えです。new mongo.ObjectID();手動でstackoverflow.com/a/56106999/4701635
Paresh Barad

回答:


18

node.jsを使用してからしばらく時間が経過しましたが、私は手助けできるかもしれないと思います。

まず、ノードでは、スレッドが1つしかなく、コールバックを使用することになっています。コードで何が起こるかというと、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
})

私は約2年間node / jsをコーディングしておらず、これもテストしていませんが、基本的な考え方は成り立つはずです。busyループを使用せず、コールバックを使用してください。ノード非同期パッケージを確認することをお勧めします。


4
Math.randomは、真にランダムなIDが必要な場合、特に、予測不可能/暗号的に安全である必要がある場合は、不適切な選択です。
Jecho Jekov

326

NPM uuidパッケージをインストールします(ソース:https : //github.com/kelektiv/node-uuid):

npm install uuid

あなたのコードでそれを使用してください:

var uuid = require('uuid');

次に、いくつかの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'

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

** UPDATE 7.x
そして、上記の使用法も廃止されたので、このパッケージを次のように使用します。

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

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

おかげで、私はそれをデータベースクエリで行う必要があります。:)
フクロウ

@フクロウ私はあなたが何を意味するのか理解できません。SQLでは?
Vinz243 2014

51
dbクエリの場合、どのような違いがありますか?一意のIDを持っているので、データベースとの通信に使用するインターフェイスで使用します。
jraede 14

パッケージuuidとnode-uuidの違いは何ですか?
ishandutta2007 2017年

5
@ ishandutta2007 node-uuidは非推奨になりました:「非推奨:代わりにuuidパッケージを使用してください。」
diutsu 2017

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 2016年

5
ランダムですか、それとも一意ですか?ランダム関数について詳しく説明してください。
Maximi '19

「暗号的に強力な疑似ランダムデータを生成します。」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
アイオン

1
これにより、非推奨の警告が発生します。
Razze

34

別のアプローチは、npm のshortidパッケージを使用することです

使い方はとても簡単です:

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

そしていくつかの魅力的な機能があります:

ShortIdは、驚くほど短い非順次のURLフレンドリーな一意のIDを作成します。URL短縮、MongoDBおよびRedis ID、およびユーザーが見る可能性のあるその他のIDに最適です。

  • デフォルトでは、URLに適した7-14文字:AZ、az、0-9、_-
  • ノンシーケンシャルなので、予測できません。
  • 重複することなく、任意の数のIDを生成できます。
  • IDを繰り返すことなく、アプリを何度でも再起動できます。

「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は、真にランダムなIDが必要な場合、特に、予測不可能/暗号的に安全である必要がある場合は、不適切な選択です。
Jecho Jekov

1
これは、真に普遍的に一意のIDを生成しません。
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) }
Yi Xiang Chong

3

暗号化された強力なUUIDが必要な場合は、その解決策もあります。

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

npm install generate-safe-id

なぜUUIDではないのですか?

ランダムUUID(UUIDv4)に、普遍的に一意になるのに十分なエントロピーがありません(ironic 、eh?)。ランダムUUID のエントロピーは122ビットしかないため、2 ^ 61個の IDの後でのみ重複が発生することがわかります。さらに、一部のUUIDv4実装では、暗号的に強力な乱数ジェネレータを使用しません。

このライブラリは、Node.js暗号RNGを使用して240ビットの IDを生成します。これは、2 ^ 120の IDを生成した後に最初の重複が発生することを示唆しています。人類の現在のエネルギー生産量に基づくと、この閾値は予見可能な将来のために越えることは不可能です。

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

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

9
これはgenerate-safe-id、放棄されており、セキュリティの脆弱性が修正されていないため(2018年8月現在)、ユーザーにとって答えが機能しない可能性があります
dannypaz

1

私は以下を使用していますが、サードパーティの依存関係なしで問題なく機能しています。

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

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


1

npmでhttps://www.npmjs.com/package/uniqidを使用

npm i uniqid

現在の時刻、プロセス、マシン名に基づいて、常に一意のIDを作成します。

  • 現在の時刻では、IDは常に単一のプロセスで一意です。
  • プロセスIDを使用すると、複数のプロセスから同時に呼び出された場合でも、IDは一意になります。
  • MACアドレスを使用すると、複数のマシンやプロセスから同時に呼び出されても、IDは一意です。

特徴:-

  • とても早い
  • 同時に呼び出された場合でも、複数のプロセスとマシンで一意のIDを生成します。
  • 一意性が低い、より短い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

YaroslavGaponovの答えから拡張して、最も単純な実装は単にを使用することMath.random()です。

Math.random()

実際の空間[0、1]で分数が同じになる可能性は理論的には0であり、node.jsのデフォルトの長さ16桁の10進数ではほぼ0に近くなります。また、この実装では、演算が実行されないため、算術オーバーフローも削減されます。また、10進数は文字列よりも少ないメモリを使用するため、文字列と比較してメモリ効率が向上します。

これを「Chong-Fractional-Unique-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))でも同じ長さになることがわかりました
李翔崇
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.