JavaScript Tips | 基本・共通ユーティリティ:汎用 – ランダム ID 生成

JavaScript JavaScript
スポンサーリンク

なぜ「ランダム ID 生成」が業務ユーティリティになるのか

業務コードでは、意外なほど頻繁に「一意な ID(かぶらない識別子)」が必要になります。

  • 一時的なデータのキー
  • フロント側だけで使う仮 ID
  • DOM 要素に紐づける id 属性
  • ログやトレース用のリクエスト ID
  • キャッシュのキー

こういう場面で、毎回「とりあえず Math.random() で…」とやっていると、
かぶりやすかったり、形式がバラバラになったりして、後から困ります。

そこで、「ランダム ID 生成」をユーティリティとして一本化しておくと、
「どこでも同じルールで、そこそこ安全な ID が作れる」状態になり、コードがかなり安定します。


一番シンプルなランダム ID 生成(Math.random ベース)

まずは「とりあえず動く」版を理解する

一番簡単なランダム ID 生成は、Math.random() を文字列にして使う方法です。

function randomIdSimple() {
  return Math.random().toString(36).slice(2);
}

console.log(randomIdSimple()); // 例: "k3z9p1q8"
JavaScript

ここでやっていることはこうです。

  • Math.random() は 0 以上 1 未満のランダムな数値を返す
  • .toString(36) で 36 進数(0-9 + a-z)に変換する
  • 0.xxxxx0.slice(2) で削る

これで、「英数字がランダムに並んだ文字列」が手に入ります。

ただし、これは“簡易的”であって、“強く一意”とは言えないことは覚えておいてください。
小さなツールや一時的な ID には十分ですが、「絶対にかぶってはいけない ID」には向きません。


プレフィックス付きランダム ID で用途を分かりやすくする

どこで使う ID なのかを文字列に埋め込む

業務では、「ID の見た目から用途が分かる」と便利です。
そこで、プレフィックス(接頭辞)を付けるユーティリティにしておくと読みやすくなります。

function randomId(prefix = "id") {
  const core = Math.random().toString(36).slice(2);
  return `${prefix}_${core}`;
}

console.log(randomId());          // 例: "id_k3z9p1q8"
console.log(randomId("user"));    // 例: "user_9as0f3lm"
console.log(randomId("element")); // 例: "element_x8z1k0p2"
JavaScript

これだけで、

  • "user_..." はユーザー関連
  • "element_..." は DOM 要素関連

といったように、ログやデバッグ時に「この ID 何だっけ?」となりにくくなります。


衝突リスクを下げるために「長さ」を意識する

ランダム部分を複数回つなげる

Math.random() 一発だと、ランダム部分が短くて不安なときは、
複数回つなげて長くするのが簡単な強化方法です。

function randomIdStrong(prefix = "id") {
  const part = () => Math.random().toString(36).slice(2);
  const core = part() + part(); // 2回分つなげる
  return `${prefix}_${core}`;
}

console.log(randomIdStrong()); // 例: "id_k3z9p1q8x8z1k0p2"
JavaScript

ここでの重要ポイントは、

  • 「完全に衝突しない」とは言えないが、実用上かなりかぶりにくくなる
  • ID の長さが増えるほど、衝突確率は指数的に下がる

ということです。

「フロント側の一時 ID」「画面内だけで使うキー」などには、このくらいで十分なことが多いです。


時刻+ランダムを組み合わせた ID

「いつ生成されたか」も分かる ID にする

ログやトレース用途では、「いつ生成された ID か」が分かると便利です。
その場合は、タイムスタンプとランダムを組み合わせます。

function randomIdWithTime(prefix = "id") {
  const time = Date.now().toString(36);
  const rand = Math.random().toString(36).slice(2);
  return `${prefix}_${time}_${rand}`;
}

console.log(randomIdWithTime()); // 例: "id_lsk3f9a_k3z9p1q8"
JavaScript

ここでの深掘りポイントは、

  • Date.now() はミリ秒単位の現在時刻
  • それを 36 進数にすることで、短くてそこそこ読める形になる
  • 「同じミリ秒に同じランダムが出る」確率はかなり低い

という点です。

これにより、「いつ」「どの処理で」生成された ID かを、ログから追いやすくなります。


ブラウザ環境でより安全な乱数を使う(crypto.randomUUID / crypto.getRandomValues)

crypto.randomUUID が使える場合

モダンブラウザでは、crypto.randomUUID() という便利な関数があります。

const id = crypto.randomUUID();
console.log(id); // 例: "550e8400-e29b-41d4-a716-446655440000"
JavaScript

UUID 形式の一意な ID を、暗号学的に安全な乱数で生成してくれます。
これが使える環境なら、正直これをそのまま使うのが一番楽で安全です。

プレフィックスを付けたいなら、こうすれば OK です。

function randomUuidId(prefix = "id") {
  return `${prefix}_${crypto.randomUUID()}`;
}
JavaScript

crypto.getRandomValues を使ったカスタム ID

crypto.randomUUID がない環境でも、crypto.getRandomValues が使えるなら、
より安全な乱数を使った ID 生成ができます。

function randomIdCrypto(prefix = "id", length = 16) {
  const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  const array = new Uint8Array(length);
  crypto.getRandomValues(array);

  let core = "";
  for (let i = 0; i < length; i++) {
    core += chars[array[i] % chars.length];
  }

  return `${prefix}_${core}`;
}

console.log(randomIdCrypto()); // 例: "id_k3z9p1q8x8z1k0p2"
JavaScript

ここでの重要ポイントは、

  • crypto.getRandomValuesMath.random よりも偏りが少なく、安全性が高い
  • 文字集合と長さを自分で決められるので、用途に合わせた ID が作れる

ということです。


実務での具体的な利用イメージ

一時的なフロント側の ID(まだ DB に保存されていないデータ)

例えば、画面上で「新規行」を追加するとき、
まだサーバーから正式な ID が発行されていないことがあります。

const tempId = randomId("temp"); // 例: "temp_k3z9p1q8"
rows.push({ id: tempId, name: "", status: "draft" });
JavaScript

サーバーから本物の ID が返ってきたら、
この一時 ID と紐づけて置き換える、というパターンがよくあります。

DOM 要素の id 属性に使う

ラベルと入力要素を紐づけるときなど、
ユニークな id が欲しい場面でもランダム ID は便利です。

const inputId = randomId("input");

// 仮の JSX 風
// <label for={inputId}>名前</label>
// <input id={inputId} />
JavaScript

これで、「同じ画面に同じ id が重複する」事故を避けられます。


小さな練習で感覚をつかむ

次のようなことを自分で試してみると、ランダム ID 生成の感覚がつかみやすいです。

  • randomIdSimple を 100 回呼んで、結果を配列に入れてみる
  • その配列の中に重複があるかどうかをチェックしてみる
  • ランダム部分を 1 回分と 2 回分つなげた場合で、重複の出やすさを比べてみる

そこから一歩進んで、

  • randomIdWithTime
  • randomIdStrong
  • randomIdCrypto

などを自分のプロジェクト用に少しカスタマイズしてみると、
「用途ごとに ID 生成ルールを決める」感覚が身についてきます。

大事なのは、
「とりあえず Math.random() を直書きする」のではなく、
“ランダム ID 生成”を一つのユーティリティとして扱う
ことです。

そうすると、後から仕様を変えたいとき(長さを変える、安全性を上げる、形式を揃えるなど)も、
そのユーティリティを直すだけで、プロジェクト全体の ID ルールを一括で変えられるようになります。

タイトルとURLをコピーしました