CUID v1ジェネレーター
Generate collision-resistant unique IDs (CUID v1)
生成された 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つの連結セグメントで構成されています:
セグメントは単純に連結されており——セパレーターはありません。合計長は現在のタイムスタンプ値によってわずかに変化しますが、約25文字を維持します。
CUIDが衝突を防ぐ方法
衝突耐性は、独立したエントロピーソースを重ね合わせることで得られます。最悪のシナリオ(多くのマシンで毎ミリ秒数千のIDを生成)でも、2つの同一IDの確率は極めて小さいままです。
CUID vs UUID v4
CUIDとUUID v4はどちらもクライアントサイドのID生成に広く使用されています。同じ問題に対して異なるアプローチを取っています:
| 特徴 | CUID v1 | UUID v4 |
|---|---|---|
| フォーマット | c + base36(約25文字) | 16進数グループ(ハイフン付き36文字) |
| ソート可能 | おおよそ(タイムスタンププレフィックス) | いいえ |
| URL安全 | はい(英数字のみ) | ほぼ(ハイフンはURLで有効) |
| 衝突耐性 | 高——タイムスタンプ + カウンター + フィンガープリント + ランダム | 高——122ビットのランダム |
| 予測可能性 | 部分的(タイムスタンプが見える) | なし(純粋なランダム) |
| 長さ | 約25文字 | 36文字 |
| 調整が必要 | いいえ | いいえ |
UUID v4はタイミング情報を明かさないため、セキュリティに敏感なシナリオでより安全な選択です。CUIDは、おおよそソート可能で短くハイフンのないIDが必要な場合に優位性があります——レコードがいつ作成されたかを素早く識別したいURL、ファイル名、ログでの使用に便利です。
CUID v1 vs CUID2
CUID仕様は大幅に改訂されています。違いを理解することで、プロジェクトに適したバージョンを選択できます:
| 観点 | CUID v1 | CUID v2 |
|---|---|---|
| アルゴリズム | 決定論的コンポーネント | SHA-3ベース、完全に不透明 |
| 暗号的 | いいえ | はい |
| タイムスタンプ可視 | はい | いいえ |
| フォーマット | 「c」で始まる | 「c」で始まる(設定可能) |
| npmパッケージ | @paralleldrive/cuid(非推奨) | @paralleldrive/cuid2 |
| 長さ | 約25文字 | 24文字(デフォルト、設定可能) |
新しいプロジェクトにはCUID v2が推奨される選択です。SHA-3ベースの構造により出力は不透明です——IDからタイムスタンプ、カウンター、フィンガープリントをリバースエンジニアリングすることはできません。既存のデータセットとの後方互換性が必要な場合や依存関係なしの実装が必要な場合のみCUID v1を使用してください。
ユースケース
@id 戦略としてCUIDを使用します——@default(cuid())——これによりJavaScriptエコシステムで最も広く展開されているIDフォーマットの1つになっています。コード例
公式CUID v2パッケージ(推奨)をインストールするか、依存関係なしで最小限のv1実装を書く:
// 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実装を好む場合:
// 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をデータベース主キーとして使用する:
-- 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())
}