ハッシュ・ID・乱数
ランダムIDは何文字必要?衝突確率から考えたい
使うツール
ランダムなIDを短くしたいけれど、重複が心配。そこで『8文字あれば何通りあるか』を調べるのはよい出発点ですが、候補数だけでは重複の起こりやすさは分かりません。何件作るか、各文字が偏りなく独立に選ばれるかも条件です。理論エントロピー・衝突確率ツールで条件を一つずつ変えると、文字を一つ増やす効果と、生成件数を増やす影響を比べられます。実際のIDが安全だと認定する診断ではなく、明示した生成モデルの計算です。
16種類を8文字なら、候補は2の32乗
alphabet = 16
length = 8
16⁸ = 4,294,967,296
log₂(16⁸) = 32 bits文字種数16、長さ8を入力します。0〜9とa〜fを毎回独立に等確率で選ぶモデルなら、候補数は4294967296、理論エントロピーは32ビットです。8文字だから8ビットではありません。十進数の数字10種類を8桁使う場合とは、候補数もエントロピーも変わります。ハイフンを固定位置に足しても、選択肢が増えなければランダムな情報量は増えません。
文字種数は、見た目でなく保存先が区別する値で数えます。大文字と小文字を同じものとして扱う保存先なら、Aとaを別々の選択肢として数える設計と合いません。入力前に、生成する文字集合と、比較・保存時の正規化規則を確認します。ツールは実際の文字列一覧を読み取ってこの数を推定するものではありません。
生成件数が増えると、比較する組合せも増える
k = 10,000
k × (k − 1) ÷ 2 = 49,995,000 pairs16種類・8文字のまま、生成件数を10000にすると、少なくとも一組が衝突する確率は約1.16%になります。候補が約43億あるのに意外に高く感じるのは、特定の一つと一致する確率ではなく、生成した値のどこかの組合せが一致する確率だからです。10000件には約5000万の組合せがあります。候補数に対する件数の割合だけで判断しないようにします。
結果のcollisionProbabilityは割合なので、0.01は1%です。0.01%と読めば100倍の取り違えになります。また『1%なら100件に1件のIDが重複する』という意味ではありません。指定した件数を一組として生成したとき、少なくとも一つの重複が含まれる確率です。確率の対象が一件なのか、生成した集合全体なのかを区別します。
一文字増やす効果を、件数を固定して見る
16種類なら、一文字増やすごとに候補数は16倍になります。8文字、9文字、10文字と変え、生成件数10000はそのままにすると、長さの効果だけを比較できます。文字種と件数まで同時に変えると、どの条件が結果を動かしたかが分かりにくくなります。まず一つずつ変え、採用候補が決まったら予定する最大件数でも確認します。
生成件数には、一回のバッチだけでなく、同じ名前空間で衝突して困る全体の件数を入れます。一日10000件でも、同じ表へ何年も保存するなら一日分だけでは足りません。別の場所へ分けて再利用できるかは、システムの識別規則次第です。IDに日付を付けたから自動的に衝突問題が消える、といった仮定を黙って加えないでください。
一様・独立という前提が、実装でも成り立つか
このツールは、各候補が等確率で独立に選ばれるモデルです。時刻や連番から作った値、偏りのある乱数、同じSeedから同じ列を再生成する処理には、そのまま適用できません。パスワードの必須文字種のように条件付きで生成する場合も、単純な文字種数の累乗と候補集合が同じとは限りません。計算結果を採用する前に、生成するコードの規則と照合します。
件数が非常に大きい条件では、ツールは近似の適用条件も確認します。対応範囲外で確率が算出されないとき、それを0%と読み替えません。可能性の数が表示されていても、確率の欄まで計算できたとは限りません。結果のmethodと未算出の表示を確認し、近似の答えを必要以上の桁で正確だと扱わないようにします。
重複しにくさと、秘密として使えることは別
公開の商品IDで重複しないことと、パスワード再設定用の秘密URLを推測されないことは違う要件です。後者には推測への強さ、生成方法、試行制限、有効期限など別の検討が必要です。このツールへ実際のパスワードを入れて安全性を診断する使い方はしません。文字種数と長さを指定するモデル計算と、個別の秘密の安全評価を混同しないでください。
最終的には、許容する衝突リスクと、重複が起きたときの検出・再生成などの扱いを決めます。確率が低いから一意性チェックを不要と即断せず、保存先の制約や並行処理も確認します。記事の数値は長さ選びの比較例であり、どのサービスにも共通する推奨文字数ではありません。