UUIDは他のIDと衝突しないIDを生成するために用いられるID生成アルゴリズムだそうです.本日は最近触ったばっかのElixirをつかってUUIDを生成する方法をまとめたいと思います.
#UUIDとは
16進数表記で「XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX」の32桁で表されるIDだそうです.UUIDにはいくつかバージョンが有るそうです.
Version | 生成方法 |
---|---|
1 | 時刻とMACアドレスを元にするもの |
2 | DCEセキュリティバージョン |
3 | バイト列を元にするバージョン.MD5ハッシュを使用 |
4 | ランダム生成するバージョン |
5 | バイト列を元にするバージョン.SHA1ハッシュを使用 |
基本的に用いられるのはバージョン1かバージョン4が用いられるそうです.バージョン1は時刻とMACアドレスを元に生成するためにユニークなIDを生成することができますが短時間に端末でアクセスして生成すればそのIDからMACアドレスを解析できてしまうため匿名性を犠牲にしています.逆にバージョン4はランダムに生成するために衝突する可能性がありますが,匿名性は担保されます.基本的にはバージョン4を使ってもほとんど衝突しないので問題ないとのことです.
#ElixirでUUIDを使う
まずはmixの準備
mix new example
cd example
mix test
./deps.getのExample.MixProject内のdepsを編集し,UUIDライブラリを追加
defp deps do
[
{ :uuid, "~> 1.1" } # UUIDを使うためのライブラリ
]
end
そのあとmixで変更内容を読み取る
mix deps.get
32文字のUUIDを生成
#UUIDをハイフンなしの大文字で生成
iex(1)> uuid_up = UUID.uuid4(:hex) |> String.upcase()
"A0554870EC964556837BDAD67A6D8662"
32文字は長いので26文字の小文字の英数字のIDに圧縮
#UUIDを16進数からBase32へ変更
iex(2)> uuid_base32 = uuid_up |> Base.decode16()|> elem(1) |> Base.encode32()
"UBKUQ4HMSZCVNA333LLHU3MGMI======"
# UUIDのパディング("=")を削除し,小文字に変換
iex(3)> String.replace(uuid_base32, "=", "") |> String.downcase()
"ubkuq4hmszcvna333llhu3mgmi
これより短くするにはBase64を使えば22文字にまで減らせるが大文字と小文字の区別が必要になります.
#参考
UUIDの基礎
https://ja.wikipedia.org/wiki/UUID
http://blog.katty.in/5124
https://www.sohamkamani.com/blog/2016/10/05/uuid1-vs-uuid4/
ID生成アルゴリズムまとめ
https://qiita.com/j5ik2o/items/1799887fec241c10af39
mixの基礎
https://elixirschool.com/ja/lessons/basics/mix/
UUIDのAPIドキュメント
https://hexdocs.pm/uuid/readme.html
Baseのドキュメント
https://hexdocs.pm/elixir/Base.html
UUIDの圧縮
https://blog.kishikawakatsumi.com/entry/20131031/1383235295
http://www.hoshilabo.net/2018/02/22/uuid(128bit)を可逆短縮する手法/
Elixirの他のUUIDドキュメント
https://hexdocs.pm/ecto/Ecto.UUID.html
https://hexdocs.pm/shortuuid/ShortUUID.html