← ハシトシステム トップ English ツール ブログ
設定
結果
0
この設定で作れる組み合わせの数
0
1パーセントの確率で衝突するまで
文字種

長さ21がどこから来た数字なのか

NanoID の既定は「URL に置ける64種類の文字」を21個並べる形です。64 の21乗は 2 の126乗、約 8.5 x 10 の37乗です。UUID v4 のランダム部分は122ビット、約 5.3 x 10 の36乗なので、既定の NanoID はそれより少し大きい規模になります。つまり21という長さは、UUID と同等以上の強さを36文字ではなく21文字で得るために選ばれた値です。短くしたぶんだけ弱くなるので、長さを変えるときは組み合わせの数がどう動くかを見てから決める必要があります。このツールが年数を一緒に出しているのはそのためです。

使う文字を減らしても同じことが起きます。たとえば数字だけの10種類にすると、1文字あたりの情報量は約6ビットから約3.32ビットへ落ちます。同じ強さを保つには長さを倍近くにしなければなりません。「短くしたい」と「文字種を絞りたい」は、どちらも同じ予算を削る操作です。

剰余で作ってはいけない理由

乱数のバイトから文字を選ぶとき、単純に「文字数で割った余り」を使うと、割り切れないぶんだけ先頭側の文字が出やすくなります。256 を 62 で割ると 4 余り 8 なので、最初の8文字だけ 5 回、残りの54文字は 4 回の割り当てになる、という偏りです。このツールは NanoID 本家と同じく、文字数を覆う最小のビットマスクで切り出し、範囲外の値は捨てる方式にしています。捨てるぶん乱数を余分に読みますが、どの文字も同じ確率になります。

設定1文字あたり21文字での組み合わせ近いもの
64種類(既定)6ビット約 8.5 x 10^37(2^126)UUID v4 のランダム部分(約 5.3 x 10^36)より少し大きい
62種類(英数字)約5.95ビット約 4.4 x 10^37記号を使えない場所向け。ほぼ同じ規模
36種類(小文字と数字)約5.17ビット約 4.8 x 10^32大文字を使えない場所向け
16種類(16進)4ビット約 1.9 x 10^25(2^84)ハッシュの一部を切ったもの
10種類(数字)約3.32ビット10^21短縮コード。長さを増やして補う

乱数はブラウザの crypto.getRandomValues から取っています。安全な乱数を取れない環境では、その旨を表示して生成しません(推測できる乱数へ黙って切り替えません)。

よくある質問(FAQ)

NanoID の既定の長さが21なのはなぜですか?

64種類の文字を21個並べると、組み合わせは 64 の 21 乗で、2 の 126 乗、約 8.5 x 10 の 37 乗になります。UUID v4 のランダム部分は122ビット、約 5.3 x 10 の 36 乗なので、既定の NanoID はそれより少し大きい規模です。UUID と同等以上の強さを、36文字ではなく21文字で得るための長さです。

UUID とはどう使い分けますか?

決められた形式が要る場面、たとえばデータベースの UUID 型や外部仕様が指定している場合は UUID を使います。自分のアプリのURLやファイル名に置くだけなら、短くて記号が2種類しか入らない NanoID のほうが扱いやすくなります。

衝突までの年数はどう計算していますか?

誕生日問題の近似式 k = ルート(2 x N x ln(1 / (1 - p))) を使い、N を「文字種の数の長さ乗」、p を1パーセントとしています。得られた k を1時間あたりの生成数で割って年に直しています。桁が大きいので対数で計算しています。

生成した ID はサーバーへ送られますか?

いいえ。乱数はブラウザの crypto.getRandomValues から取り、生成もこのページの中だけで行っています。安全な乱数を取れない環境ではその旨を表示し、推測できる乱数へ黙って切り替えることはしません。