背景
WEB上でURLを知っている人だけに情報を伝えるページを用意する際に、URL safeで短くて衝突しないIDを生成したい欲求に駆られた。
要件を整理
- URLとして利用可能な文字列で構成されること
- 不可逆でよし
- 他ページのURLおよび同ロジックで生成される重複がおきないこと
- 文字長は長くても別にいいが、12桁〜24桁くらいか(なんとなく)
- ページ投稿毎に生成なのでパフォーマンスはそこまで気にしない
ロジック考える
UUIDつかってうまいことやる。
やってみた
MACで試すと
uuidgen
374398CF-10DE-4546-847A-A8CBFCD39B07
ハイフン邪魔だから(一意性に問題なし)
uuidgen | tr -d '-'
40D86A4807C840579C60D8677D3C2C9A
これで32桁。もっと短くするならUUIDを16進文字列ではなく本来の128bitバイナリ変換してbase64にする
uidgen | tr -d '-' | xxd -r -p | base64
86/+73DiQBeWEfsB0cMlRg==
base64だと/とか+とか出力されるしパディングの=が邪魔
パディングは消しても一意性に問題ないから
uuidgen | tr -d '-' | xxd -r -p | base64 | tr '+/' '-_' | tr -d '='
hln3YGorRaK6QsaS7O5QCg
これで22文字になった。要件クリア。
最後に
そもそもurl safeで26桁出力するULID使えばいいじゃん、って後で気がついたけれど
01K4RTJ12HFZ1WC4024G7EN7PM
みたいに全部大文字だし、いかにもULIDで作りました!って感じだから、4桁少ない前述の方法を採用で。