ULIDをブラウザで生成する:UUIDとの違いとCrockford Base32の実装

主キーやログのIDに UUID v4 を使っていると、「生成した順に並ばない」ことが地味に効いてくる。データベースのインデックスは挿入位置がばらけて断片化しやすく、一覧を時系列で出したいだけなのに別途タイムスタンプ列が要る。ULID(Universally Unique Lexicographically Sortable Identifier)は、この不満を埋める128ビットの識別子だ。

要点だけ先に言うと、ULIDは先頭にミリ秒タイムスタンプを持つので、文字列として辞書順に並べると生成時刻順になる。表記は26文字・ハイフンなしで、36文字のUUIDより短くURLにも使いやすい。

UUID v4 と ULID の使い分け

UUID v4 ULID
構造 122ビットの乱数 48ビット時刻 + 80ビット乱数
表記 36文字(ハイフン区切り) 26文字(ハイフンなし)
ソート 順序に意味なし 辞書順=生成時刻順
向く用途 時刻を漏らしたくない 時系列の主キー・ログ

ランダム性だけが欲しいなら UUID v4、時系列に並ぶ主キーが欲しいなら ULID。生成時刻を推測されたくない場面では、逆に ULID を避けて v4 を選ぶ。

構造:48ビット時刻 + 80ビット乱数

ULIDの128ビットは、先頭48ビットが「1970年からのミリ秒」、残り80ビットが乱数だ。これを Crockford Base32 で符号化して26文字にする。Crockford Base32 は 0-9 と、紛らわしい I, L, O, U を除いた A-Z の32文字を使う。

1
var ENC = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford Base32

タイムスタンプ48ビットは10文字、乱数80ビットは16文字に符号化され、合わせて26文字になる。

実装(依存ゼロ)

乱数は暗号学的に安全な crypto.getRandomValues を使う。ブラウザでもNode 19+でもグローバルに crypto が使える。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var ENC = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';

// 48ビットの時刻を10文字に(先頭から5ビットずつ)
function encodeTime(t, len) {
var s = '';
for (var i = len - 1; i >= 0; i--) {
var mod = t % 32;
s = ENC.charAt(mod) + s;
t = (t - mod) / 32;
}
return s;
}

// 乱数を len 文字に
function encodeRandom(len) {
var bytes = new Uint8Array(len);
crypto.getRandomValues(bytes);
var s = '';
for (var i = 0; i < len; i++) s += ENC.charAt(bytes[i] % 32);
return s;
}

function ulid(now) {
return encodeTime(now || Date.now(), 10) + encodeRandom(16);
}

console.log(ulid()); // 例: 01K0F8Q2R7 8ZC3V... のような26文字

encodeTime は数値を32進数に変換しているだけだ。JavaScriptの数値は倍精度浮動小数点だが、48ビット(約281兆)は安全整数(2^53)の範囲内なので Date.now() のミリ秒をそのまま扱える。

「同じミリ秒」での順序について

上の実装は、同じミリ秒内で複数生成すると乱数部が独立に振られるため、その中での生成順までは保証しない。厳密な単調増加(同一ミリ秒でも生成順にソート)が必要なら、公式仕様にある「同じミリ秒なら前回の乱数部に+1する」monotonic factory を実装する。多くの用途ではミリ秒精度の順序で十分なので、まずはシンプルな実装で始めて問題ない。

動かして試す

件数を指定してまとめて生成し、コピーできるツールを公開している。値の見た目や、生成順に並ぶことを確認したいときにどうぞ。

なお、時系列ソート可能なIDが欲しいだけなら、UUID仕様に取り込まれた UUID v7 も選択肢になる。標準のUUID形式を保ちたいならv7、より短い表記が欲しいならULID、と好みで選べばよい。


ULIDをブラウザで生成する:UUIDとの違いとCrockford Base32の実装
https://blog.hashito.biz/2026/07/17/ulid-generate-browser-crockford-base32-uuid-alternative/
著者
hashito
作成日
2026年7月17日
著作権