CUID v1ジェネレーター

Generate collision-resistant unique IDs (CUID v1)

件数

生成された CUID

「生成」をクリックして CUID を作成

CUID v1 はレガシー形式です。新しいプロジェクトには CUID2 を使用してください。

CUIDとは何ですか?

CUID(衝突耐性ユニーク識別子)は、中央コーディネーターなしに分散システムでうまく機能するユニークIDを生成するオープンソースアルゴリズムです。単純なUUIDとは異なり、CUIDは水平スケーラブルになるよう設計されています——複数のサーバーまたはブラウザータブが独立してIDを生成でき、衝突リスクは最小限です。

すべてのCUIDは小文字の c で始まり、フォーマットが一目でわかります。残りの文字はすべて小文字の英数字(base36)なので、CUIDはURL安全で、追加のエンコードなしにURLパスセグメントやデータベースの主キーとして直接使用できます。

元のCUID仕様(v1)はEric Elliottによって作成され、npmパッケージ cuid を通じて普及しました。現在は暗号セキュリティを提供するCUID v2に取って代わられています。このページ——および上記のジェネレーター——はCUID v1 IDを生成します。これはプロダクションコードベースで今も広く見られるクラシックなフォーマットです。

CUIDの構造

CUID v1は約25文字の長さで、それぞれ異なる種類のエントロピーを持つ5つの連結セグメントで構成されています:

: clrc4gkwz001ag2hs3k7f9m2q
cプレフィックス常に文字「c」——CUIDを示す
lrc4gkwzタイムスタンプbase36のミリ秒タイムスタンプ(約8文字)
001aカウンター4文字のbase36カウンター——同一ミリ秒の衝突を防ぐ
g2hsフィンガープリント4文字のbase36ホストフィンガープリント(ブラウザー/環境情報)
3k7f9m2qランダム8文字のbase36ランダムブロック——2つの32ビット値

セグメントは単純に連結されており——セパレーターはありません。合計長は現在のタイムスタンプ値によってわずかに変化しますが、約25文字を維持します。

CUIDが衝突を防ぐ方法

衝突耐性は、独立したエントロピーソースを重ね合わせることで得られます。最悪のシナリオ(多くのマシンで毎ミリ秒数千のIDを生成)でも、2つの同一IDの確率は極めて小さいままです。

ミリ秒タイムスタンプ
最初のセグメントは現在時刻をbase36でエンコードします。異なる時点で生成されたIDは、作成時刻で自動的に辞書順にソートされます——ページネーションとデバッグに役立ちます。
単調カウンター
同一プロセス内では、4文字のカウンターは生成されるIDごとに増加します。同じマシンで同じミリ秒に2回の呼び出しが発生しても、カウンターは毎ミリ秒最大65,536個のIDの一意性を保証します。
マシンフィンガープリント
環境固有のデータ(Node.jsではプロセスID + ホスト名;ブラウザーでは画面サイズ + navigator情報)から派生したハッシュ。これにより、同じカウンター値で完全に同じミリ秒に別々のホストで生成されたIDが区別されます。
ランダムブロック
最後の8文字は、base36でエンコードされた2つの独立した32ビットランダム値から生成されます。これにより、2台のマシンのフィンガープリントが偶然同じ値にハッシュされた場合でも衝突を防ぐ最終的なエントロピー層が追加されます。

CUID vs UUID v4

CUIDとUUID v4はどちらもクライアントサイドのID生成に広く使用されています。同じ問題に対して異なるアプローチを取っています:

特徴CUID v1UUID v4
フォーマットc + base36(約25文字)16進数グループ(ハイフン付き36文字)
ソート可能おおよそ(タイムスタンププレフィックス)いいえ
URL安全はい(英数字のみ)ほぼ(ハイフンはURLで有効)
衝突耐性高——タイムスタンプ + カウンター + フィンガープリント + ランダム高——122ビットのランダム
予測可能性部分的(タイムスタンプが見える)なし(純粋なランダム)
長さ約25文字36文字
調整が必要いいえいいえ

UUID v4はタイミング情報を明かさないため、セキュリティに敏感なシナリオでより安全な選択です。CUIDは、おおよそソート可能で短くハイフンのないIDが必要な場合に優位性があります——レコードがいつ作成されたかを素早く識別したいURL、ファイル名、ログでの使用に便利です。

CUID v1 vs CUID2

CUID仕様は大幅に改訂されています。違いを理解することで、プロジェクトに適したバージョンを選択できます:

観点CUID v1CUID v2
アルゴリズム決定論的コンポーネントSHA-3ベース、完全に不透明
暗号的いいえはい
タイムスタンプ可視はいいいえ
フォーマット「c」で始まる「c」で始まる(設定可能)
npmパッケージ@paralleldrive/cuid(非推奨)@paralleldrive/cuid2
長さ約25文字24文字(デフォルト、設定可能)

新しいプロジェクトにはCUID v2が推奨される選択です。SHA-3ベースの構造により出力は不透明です——IDからタイムスタンプ、カウンター、フィンガープリントをリバースエンジニアリングすることはできません。既存のデータセットとの後方互換性が必要な場合や依存関係なしの実装が必要な場合のみCUID v1を使用してください。

ユースケース

分散データベース
複数のデータベースシャードまたはマイクロサービスが、シーケンステーブルや中央IDサービスなしに独立して主キーを生成でき、単一障害点を排除します。
クライアントサイドID生成
ブラウザーはサーバーに送信する前に新しいレコードにCUIDを割り当てることができ、楽観的UIアップデートが可能になり、サーバー割り当てIDを取得するための往復が不要になります。
オフラインファーストアプリ
接続なしで動作するモバイルまたはPWAアプリは、同期を生き延びる安定したIDを持つレコードを作成できます——デバイスがオンラインに戻ったときも競合なし。
URLスラッグ
CUIDには英数字のみが含まれており、パーセントエンコードなしにURLパスに直接埋め込むことができます。タイムスタンププレフィックスにより大まかな作成時刻順が追加されます。
イベント / ログ相関
タイムスタンプが最初のセグメントにエンコードされているため、CUIDでタグ付けされたログエントリは、分散ログアグリゲーターをまたいでも作成時刻でおおよそソートできます。
ORM / Prismaのデフォルト
PrismaはString主キーのデフォルト @id 戦略としてCUIDを使用します——@default(cuid())——これによりJavaScriptエコシステムで最も広く展開されているIDフォーマットの1つになっています。

コード例

公式CUID v2パッケージ(推奨)をインストールするか、依存関係なしで最小限のv1実装を書く:

JavaScript / TypeScript
// npm install @paralleldrive/cuid2  (recommended — CUID v2)
import { createId } from '@paralleldrive/cuid2'

const id = createId()
// → 'tz4a98xxat96iws9zmbrgj3a'

// Custom length
import { init } from '@paralleldrive/cuid2'
const createShortId = init({ length: 10 })
createShortId() // → 'zxp1l6mf4c'

v1アルゴリズムの依存関係なしNode.js実装を好む場合:

Node.js (no dependencies)
// Pure Node.js — CUID v1 style (no dependencies)
let counter = 0

function pad(str, size) {
  return str.padStart(size, '0').slice(-size)
}

function fingerprint() {
  const os = require('os')
  const source = [process.pid, os.hostname().length].join('')
  let hash = 0
  for (const c of source) {
    hash = ((hash << 5) - hash) + c.charCodeAt(0)
    hash |= 0
  }
  return pad(Math.abs(hash).toString(36), 4)
}

function cuid() {
  const timestamp = Date.now().toString(36)
  const cnt       = pad((counter++ & 0xffff).toString(36), 4)
  const fp        = fingerprint()
  const rnd       = pad(Math.floor(Math.random() * 0xffffffff).toString(36), 4)
              + pad(Math.floor(Math.random() * 0xffffffff).toString(36), 4)
  return 'c' + timestamp + cnt + fp + rnd
}

console.log(cuid()) // → 'clrc4gkwz001ag2hs3k7f9m2q'

PrismaとPostgreSQLでCUIDをデータベース主キーとして使用する:

Prisma / SQL
-- Use CUID as a primary key in PostgreSQL
CREATE TABLE users (
  id   TEXT        PRIMARY KEY DEFAULT gen_cuid(),
  name TEXT        NOT NULL,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- Prisma schema (auto-generates CUID by default)
model User {
  id        String   @id @default(cuid())
  name      String
  createdAt DateTime @default(now())
}

よくある質問

CUIDはURL安全ですか?
はい。CUID v1は小文字と数字(base36エンコード)のみを使用しており、これらはすべてURL安全文字です。URLパスやクエリパラメーターでCUIDを使用する際にパーセントエンコードは不要です。
CUIDは暗号的に安全ですか?
いいえ。CUID v1はMath.random()を使用し、可視のタイムスタンププレフィックスを公開します。セッショントークンやパスワードリセットリンクなどのセキュリティに敏感な目的には適していません。これらのユースケースには、crypto.randomUUID()またはCUID v2を使用してください。
CUID vs NanoID——どちらを選ぶべきですか?
NanoIDは暗号的に安全で、短く(デフォルト21文字)、カスタマイズ可能なアルファベットを使用します。セキュリティが重要な場合や短いIDが必要な場合はNanoIDを選択してください。おおよそソート可能でタイムスタンププレフィックス付きの人間がデバッグしやすいIDが必要な場合はCUIDを選択してください。
CUID v1とCUID v2のどちらを使うべきですか?
CUID v2が現在の推奨です。暗号的に安全で、タイミング情報を漏洩せず、積極的にメンテナンスされています。CUID v1は依存関係なしのシンプルな実装が必要な場合やレガシーシステムをメンテナンスしている場合に役立ちます。このジェネレーターはCUID v1 IDを生成します。
CUID vs ULID——何が違いますか?
どちらもタイムスタンププレフィックスを持ち、辞書順でソート可能です。ULIDはCrockford base32(合計128ビット、48ビットタイムスタンプ + 80ビットランダム)を使用し、やや多くのランダム性を持ちます。CUIDはマシンフィンガープリントと単調カウンターを追加し、同一ミリ秒内の同一ホストでの衝突耐性を向上させます。ULIDはタイムスタンプが完全な上位ビットを占めるため、より信頼性の高いソートができます。
CUIDは一意性が保証されていますか?
中央コーディネーターなしにどのIDスキームも数学的保証を与えることはできません。CUIDはタイムスタンプ、プロセスごとのカウンター、マシンフィンガープリント、ランダムデータという4つの独立したエントロピーソースを組み合わせることで衝突を極めて起こりにくくしています。実際には、衝突はハードウェア障害よりもはるかに起こりにくいです。