JavaScriptでULIDを生成する方法

この記事では『ULID』について、

  • JavaScriptでULIDを生成する方法
  • シード時間をulid関数の引数に渡す方法
  • monotonicFactory関数を用いて、単調増加するULIDを生成する方法
  • decodeTime関数を用いて、ULIDをUNIX時間に変換する方法

などを分かりやすく説明するように心掛けています。ご参考になれば幸いです。

JavaScriptでULIDを生成する方法

ULIDは「Universally Unique Lexicographically Sortable Identifier」の略で、簡単に説明すると「生成順でソート可能なユニークなID」となります。

以下の手順を行うことで、JavaScriptでULIDを生成することができます。

JavaScriptでULIDを生成する手順

  • 「Node.js」と「Node Package Manager」がインストールされているかを確認する
  • 「package.json」ファイルを作成する
  • ULIDをインストールする
  • ULIDをインポートして関数を実行する

ではこれから上記の手順について順番に説明します。

あわせて読みたい

ULID』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

「Node.js」と「Node Package Manager」がインストールされているかを確認する

ULIDをインストールするためには、「Node.js」と「Node Package Manager(Node.js標準のパッケージ管理ツール)」がインストールされている必要があります。

「PowerShell」または「コマンドプロンプト(cmd)」を起動し、以下の2つのコマンドを1つずつ実行します。

node -v
npm -v

これらのコマンドを実行して、バージョンが正しく表示されればOKです。

npmはNode Package Managerを利用するためのコマンドです。

上記のコマンドの実行結果

参考に上記のコマンドの実行結果を下記に示します。

PS C:\Users\user01> node -v
v18.16.0
PS C:\Users\user01> npm -v
9.6.6

あわせて読みたい

「Node.js」と「Node Package Manage」のインストール方法については下記の記事で詳しく説明しています。インストールしていない方は下記のリンクからぜひチェックをしてみてください。

「package.json」ファイルを作成する

Node.jsがインストールされていることを確認したら、次に「package.json」ファイルを作成します。ここでは、パッケージ管理にnpm(node package manager)を使用して作成します。

カレントディレクトリ(現在作業しているディレクトリ)がプロジェクトのルートディレクトリであることを確認してください。その後、以下のコマンドを実行すると、「package.json」ファイルを作成することができます。

npm init -y

すでに「package.json」ファイルが存在している場合はこのコマンドは不要です。

npm init -yコマンドを実行すると、以下に示すような「package.json」ファイルが作成されます(環境によって作成されるpackage.jsonは異なります)。

{
  "name": "ulid",
  "version": "1.0.0",
  "description": "",
  "main": "ulid.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

ULIDをインストールする

次に、ULIDをインストールします。以下のコマンドをプロジェクトのルートディレクトリで実行すると、ULIDをインストールすることができます。

npm install --save-dev ulid

上記のコマンドを実行すると、ULIDが開発依存関係として「package.json」ファイルに追加されます。その結果、「package.json」ファイルは以下のように更新されます。

{
  "name": "ulid",
  "version": "1.0.0",
  "type": "module",
  "description": "",
  "main": "ulid.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ulid": "^2.3.0"
  }
}

devDependenciesULIDが追加されていることで、ULIDが正しくインストールされていることが確認できます。

後ほど、import文を用いてULIDをインポートするので、上記の「package.json」に「"type": "module"」を追加してます。

ULIDをインポートして関数を実行する

ulidをインポートして、ulid関数を実行すると、ULIDを生成することができます。

import { ulid } from 'ulid';

let value = ulid();

console.log(value);

// ログ出力
// 01HB5A8AJG6F58B057MGERAZT0

シード時間をulid関数の引数に渡す方法

シード時間(シードタイム)をulid関数の引数に渡すことができます。

例えば、ulid(10000)は、UNIXのエポック秒「協定世界時(UTC)の1970年1月1日午前0時0分0秒」から10秒後(10,000ミリ秒後)のタイムスタンプを基にULIDを生成することを意味します。

import { ulid } from 'ulid';

let value = ulid(10000);

console.log(value);

// ログ出力
// 00000009RGVXNJN5QP4W0FTN57

シード時間とは

シード時間とは、128ビットで構成されるULIDにおいて、前半48ビットのタイムスタンプ部をカスタムで設定したいときに使用するタイムスタンプ(ミリ秒単位の整数)です。

例えば、特定の過去の時間からULIDを生成したい場合や、テスト目的で特定のタイムスタンプを持つULIDを生成したい場合などにシード時間を利用します。

単調増加するULIDを生成する方法

monotonicFactory関数は単調増加するULIDを生成するための関数です。この関数を使用してULIDを生成すると、同じミリ秒内で生成されるULIDは、直前のULIDよりも必ず大きくなることが保証されます。

以下のプログラム例では、同じミリ秒内に複数のULIDを生成するために、同じシード時間を渡しています。

import { monotonicFactory } from 'ulid';

let ulid = monotonicFactory();

// 最下位のビットを1ずつ増分している。
console.log(ulid(10000)); //00000009RGSTFX0736B79TT1E1
console.log(ulid(10000)); //00000009RGSTFX0736B79TT1E2
console.log(ulid(10000)); //00000009RGSTFX0736B79TT1E3
console.log(ulid(10000)); //00000009RGSTFX0736B79TT1E4
console.log(ulid(10000)); //00000009RGSTFX0736B79TT1E5
console.log(ulid(10000)); //00000009RGSTFX0736B79TT1E6

// より小さいシード時間を渡しても、単調増加は維持される。
console.log(ulid(5000)); //00000009RGSTFX0736B79TT1E7

// より大きいシード時間を渡すと、単調増加は維持されない。
console.log(ulid(20000)); //0000000KH0YJN1DSWG84YPWY4A

monotonicFactory関数の特徴

  • monotonicFactory関数は関数を返す。
  • monotonicFactory関数が作成した関数(上記のプログラムではulid)を呼び出すことで単調増加するULIDを生成できる。
  • 同じミリ秒内で複数のULIDを生成する場合、ランダム部の最下位のビットが1ずつ増分される。
  • シード時間が直前の呼び出しよりも小さい場合でも、生成されるULIDは前のULIDよりも大きくなる。
  • シード時間が大きくなると、タイムスタンプ部がその新しい時間を反映するため、単調増加の保証は維持されない。

ULIDをUNIX時間に変換する方法

decodeTime関数を使うことで、ULIDのタイムスタンプ部を抽出して、そのミリ秒単位のUNIX時間を得ることができます。

import { ulid, decodeTime } from 'ulid';

// ULIDを生成する
let value = ulid(10000);
console.log(value); // 00000009RGMW4BG14PAXJSBQ9V

// 生成されたULIDをdecodeTime関数に渡すことで、ミリ秒単位のUNIX時間を取得する
let unix = decodeTime(value);
console.log(unix); //10000

// このUNIX時間をDateオブジェクトのコンストラクタに渡すことで、日付オブジェクトを得る
let date = new Date(unix);

// toISOStringメソッドを使用して、この日付をISO 8601形式の文字列として出力する
console.log(date.toISOString()); // 1970-01-01T00:00:10.000Z

この方法を使用すると、ULIDが生成された正確な時刻を知ることができます。

本記事のまとめ

この記事では『ULID』について、以下の内容を説明しました。

  • JavaScriptでULIDを生成する方法
  • シード時間をulid関数の引数に渡す方法
  • monotonicFactory関数を用いて、単調増加するULIDを生成する方法
  • decodeTime関数を用いて、ULIDをUNIX時間に変換する方法

お読み頂きありがとうございました。