Node.js 14.17.0以降
サードパーティライブラリを使わずとも、標準のCryptoモジュールでUUID v4を生成できる。
const crypto = require("crypto");
console.log(crypto.randomUUID());
// => 49affff9-0216-46ed-902c-b3324fd6d094
Node.js 14.17.0以前
npmのuuidモジュールを使う。
https://www.npmjs.com/package/uuid
ブラウザの場合
ブラウザでも crypto.randomUUID()
でUUIDを生成できる。
上記いずれも使えない場合
こちらで下記コードが紹介されている。これが実用に耐えるものなのかは分からない。
const crypto = require('crypto');
const UUIDGeneratorNode = () =>
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)
);
console.log(UUIDGeneratorNode()); // => 0444ae6e-2226-4ca7-9b66-b8d60dce2333
ざっくり解析すると、
まず [1e7] + -1e3 + -4e3 + -8e3 + -1e11
により'10000000-1000-4000-8000-100000000000'
という文字列が生成される。
この文字列のうち、0, 1, 8の部分を1文字ずつランダムに置換する。
4を置換しないのは、この位置はUUIDのバージョンを表し、UUID v4では4で固定だから(参考:wikipedia)。
同様に8の部分はバリアントを表し、c=8
ならc ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))
は8, 9, a, bのいずれかになる。つまりバリアント1のみとなる。
1と0の部分で置換結果に差異はないようだ。置換前文字列の生成手法のため偶有的に0と1に分かれていると思われる。なので、関数の定義を
const UUIDGeneratorNode2 = () =>
'00000000-0000-4000-8000-000000000000'.replace(/[08]/g, c =>
(c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)
);
と変えても結果は同じだと思われる。