ランダム文字列ユーティリティで何をしたいか決める
「ランダム文字列」と一口に言っても、目的で“正解の実装”が変わります。
短い一時トークン(画面遷移の一時キー)
テストデータ用の適当なID
ユーザーに見せる仮パスワードや招待コード
業務で一番大事なのは、「セキュリティが必要かどうか」を最初に決めることです。
セキュリティがいらない用途(テストデータ、見た目だけのランダムID)なら Math.random で十分。
パスワード・トークン・認証系なら、必ず crypto.getRandomValues を使うべきです。
ここを曖昧にしたまま書き始めると、「なんとなく動くけど危ないコード」が量産されます。
まずは「非セキュア用途」向けの基本ランダム文字列
文字セットと長さを決める
一番よくある要件はこんな感じです。
「英大文字・英小文字・数字からなる、長さ N のランダム文字列がほしい」
このときは、まず「使う文字の集合(文字セット)」を決めます。
const DEFAULT_CHARS =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
JavaScriptそして、「この文字セットからランダムに1文字ずつ選んで、指定の長さだけ連結する」という発想で作ります。
Math.random を使ったシンプル実装
function randomString(length, chars = DEFAULT_CHARS) {
if (length <= 0) return "";
let result = "";
for (let i = 0; i < length; i++) {
const index = Math.floor(Math.random() * chars.length);
result += chars[index];
}
return result;
}
JavaScriptポイントを噛み砕きます。
length が 0 以下なら空文字を返す(ガード)。chars は「使ってよい文字の集合」。Math.random() は 0 以上 1 未満の乱数を返すので、それに chars.length を掛けてインデックスを決める。Math.floor で小数点以下を切り捨てて、0〜chars.length - 1 の整数にする。
実際に動かしてみるとこうなります。
randomString(8); // 例: "aZ3kP0xQ"
randomString(16); // 例: "f9Gh2LmN0pQrStUv"
randomString(6, "0123456789"); // 例: "493027"(数字だけ)
JavaScriptテストデータや一時的なIDなど、「バレても困らない用途」なら、このレベルで十分です。
セキュリティが絡むなら crypto.getRandomValues を使う
なぜ Math.random ではダメなのか
Math.random() は「擬似乱数」です。
“それっぽくランダム”に見えるだけで、暗号的には安全ではありません。
アルゴリズムや内部状態が分かると、出てくる値をある程度予測できてしまいます。
だから、次のような用途には使ってはいけません。
パスワード生成
ログイン用トークン
パスワードリセット用URLのトークン
APIキー
こういうときは、OS が提供する安全な乱数を使う必要があります。
ブラウザや Node.js では、それをラップした crypto.getRandomValues が使えます。
crypto.getRandomValues を使った安全なランダム文字列
function secureRandomString(length, chars = DEFAULT_CHARS) {
if (length <= 0) return "";
const array = new Uint32Array(length);
crypto.getRandomValues(array);
let result = "";
for (let i = 0; i < length; i++) {
const index = array[i] % chars.length;
result += chars[index];
}
return result;
}
JavaScript重要ポイントを丁寧に説明します。
Uint32Array(length) で「長さ N の整数配列」を用意する。crypto.getRandomValues(array) で、配列の各要素に“安全な乱数”を詰めてもらう。
各要素は 0〜2³²-1 の範囲の整数なので、それを chars.length で割った余り(%)をインデックスとして使う。
これで、「各文字の選択に暗号論的に安全な乱数」を使えるようになります。
使い方は Math.random 版と同じです。
secureRandomString(32); // セキュアな32文字のランダム文字列
JavaScriptパスワードやトークンなど、「推測されたら困るもの」は必ずこちらを使う、というルールにしておくと安全です。
実務での使いどころと設計のコツ
用途ごとに関数を分ける
おすすめは、用途ごとに関数を分けておくことです。
export function randomString(length, chars) {
// 非セキュア用途(テストデータなど)
}
export function secureRandomString(length, chars) {
// セキュア用途(トークンなど)
}
JavaScript呼び出し側のコードを読むだけで、「これはセキュアな乱数を使っている」「これはテスト用だ」と分かるようにしておくと、後から見ても迷いません。
文字セットを一箇所にまとめる
よく使う文字セットは、定数としてまとめておくと便利です。
export const CHARS_ALNUM =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
export const CHARS_HEX = "0123456789abcdef";
JavaScriptこうしておくと、
secureRandomString(32, CHARS_HEX); // 16進文字だけのトークン
JavaScriptのように、用途に応じて簡単に切り替えられます。
ちょっとだけ手を動かしてみる
ブラウザのコンソールで、次の順番で試してみてください。
randomString(8);
randomString(8);
randomString(8);
secureRandomString(32);
secureRandomString(32);
JavaScript「毎回違う値が出る感覚」と、
「長さや文字セットを変えるとどう変わるか」を体で掴んでみてください。
そのうえで、自分のプロジェクトに
export const CHARS_ALNUM = "...";
export function randomString(...) { ... }
export function secureRandomString(...) { ... }
JavaScriptの3点セットを置いて、
「ランダム文字列が欲しくなったら必ずここを通す」というルールにしてみてください。
それができた瞬間、あなたのコードは
「その場しのぎの Math.random 連打」から、
目的に応じてきちんと設計されたランダム文字列ユーティリティに、一段レベルアップします。
