logo hsb.horse
← スニペット一覧に戻る

Snippets

crypto.randomUUID の Polyfill

crypto.randomUUID 関数のポリフィル実装。全ブラウザでサポートされているため新規実装の必要はないが、UUID v4 の仕組みを学ぶ参考になる。

公開日: 更新日:

全ブラウザで crypto.randomUUID がサポートされているため、今さらこの polyfill を実装する必要はない。しかし UUID v4 の仕組みを理解するには良い題材になる。

コード

type UUID = `${string}-${string}-${string}-${string}-${string}`;
const FN_NAME = "randomUUID";
const BASE_STR = [1e7, 1e3, 4e3, 8e3, 1e11].join("-");
/**
* UUID v4 を生成する
* ブラウザが randomUUID をサポートしていない場合はポリフィル実装を実行
*/
export function randomUUID(): UUID {
const api = crypto;
if (FN_NAME in api) return api[FN_NAME]();
return BASE_STR.replace(/[018]/g, replacer) as UUID;
}
function replacer(char: string): string {
const random = crypto.getRandomValues(new Uint8Array(1))[0];
const int = Number.parseInt(char);
return (int ^ (random & (15 >> (int / 4)))).toString(16);
}

UUID v4 の仕組み

UUID v4 はランダムに生成される 128 ビットの識別子だ。標準形式は 8-4-4-4-12 の 36 文字(ハイフン含む)。

  • xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
  • 13 文字目は必ず 4(バージョンを示す)
  • 17 文字目は 8, 9, a, b のいずれか(variant を示す)

実装の解説

BASE_STR は “10000000-1000-4000-8000-100000000000” というテンプレートになる。replace で 0, 1, 8 の各文字をランダム値に置き換えることで UUID を生成している。

crypto.getRandomValues で暗号的に安全な乱数を取得し、ビット演算で UUID の各位置に埋め込んでいく。

注意点

  • 本番コードではネイティブの crypto.randomUUID を使うべき
  • この実装は学習目的向け
  • パフォーマンスはネイティブ実装に劣る