UUID生成(v4・v7)
UUIDをまとめて作ります。v4は完全に無作為なので、作られた順は値に残りません。v7は先頭のビットに時刻を置くので、作られた順に並びます。データベースの主キーにするなら、索引が素直に振る舞うのはv7のほうです。
作られた順に並びます
ブラウザの中で作られます。 サーバを通らないので、同じ値が誰かに渡っていることはありません。乱数は crypto.getRandomValues から取っています。
v7 の読み方
先頭の十二桁の十六進数が Unix 時刻(ミリ秒)です。その後ろの 7 が版で、十七文字目が 8〜b なら標準の変種です。7 の後ろの三桁は同じミリ秒の中の順番です — 時刻が変わると乱数から始め直し、同じミリ秒の中では一つずつ上がります。ですから一覧で先頭の十六桁がほぼ同じで、後ろだけ違うのが正常です。時刻はこの端末の時計なので、時計の狂った機械で作ったものと混ぜると、順番もその分ずれます。
短い ID の正体
A–Z・a–z・0–9・_・- の六十四文字から二十一文字を引きます。一文字が 6 ビットなので 126 ビット — v4 の乱数 122 ビットより多いのです。短いから弱いのではなく、表記が密なのです。ハイフンで区切られず、URL に入れてもエンコードするものがありません。長さを変える欄はありません。
乱数はどこから来るか
三つともブラウザの crypto を使います。Math.random は予測できるため識別子に使ってはいけませんが、ここでは使っていません。値は開いたときと種類・個数を変えるたびに新しく作られ、どこにも保存されないので、必要なものは複製しておいてください。作り直すと前のものは消えます。
よくある質問
v4とv7、どちらを使うべきですか
主キーならv7です。v4は完全に無作為なので、新しい値が索引の任意の場所に入り、書き込みの性能が落ちます。v7は先頭48ビットがミリ秒の時刻なので、値が順に追加されます。その代わり作られた時刻が値から見えるので、それが困る場面ではv4をお使いください。
まとめて作っても順番は保たれますか
保たれます。同じミリ秒の中の順番は12ビットの計数器が保ちます。時計だけで作ると、まとめて作った分がすべて同じミリ秒に入り、後ろの無作為なビットで順番が混ざってしまい、v7を使う理由そのものが消えます。
v4が衝突することはありますか
実際には起きません。無作為な122ビットあるので、毎秒10億個を100年作り続けても衝突する見込みは無視できます — ただし 乱数がまともであれば の話であり、だからここではブラウザの暗号用の乱数を使っています。
短いIDは安全ですか
この画面の短いIDは21文字で、含まれる乱数は126ビットです — UUID v4 の122ビットより多いくらいです。短いのは文字数であって安全性ではありません。危うくなるのは、それをさらに切って使うときです。URLに出る値にはもちろん、他人に推測されては困る値にもこの長さで足ります。
大文字で出ますか
小文字です。RFC 9562 は、作るときは小文字で書き、読むときはどちらも受け付けるよう定めています。受け取る側はたいてい区別しませんが、文字列として比べるコードがあるなら、どちらかに統一してください。
v1 や v5 はありませんか
ありません。v1 は MAC アドレスが入り、どの機械で作ったかが露わになります。v5 は名前をハッシュするもので、乱数の生成器ではありません。順序が要るなら v7、そうでなければ v4 で十分です。
貼り付けたものはサーバへ送られますか
送られません。すべてブラウザの中で動き、送信も保存もしません。だからこそ、ふつうならウェブページに貼り付けない社内の設定ファイルや本番のクエリにも使えます。通信を切ったままでも動きます。