Generate Sequential UUIDv4 in Elixir
Contents
The idea is simple. Sequential UUIDv4 (128 bit) consists of unix timestamp (32 bit) + random bytes (96 bit)
UUIDv4
Basic form of normal UUIDv4 (128 bit) in hex numbers (32 digits) 1 :
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
- Each digit is 4 bit.
xis any random hexadecimal digityis either8,9,A, orB4andyare version flags indicate version 4 UUID 2yis 4 bit:10zzwherezis random bit. Hence, the possible value ofyis1000(8),1001(9),1010(A),1011(B)
Sequential UUIDv4
A bit modification on normal form where first 32 bits are UNIX timestamp (or 8 digit in hex number) and remaining bits comply with UUIDv4 spec as explained above.
tttttttt-xxxx-4xxx-yxxx-xxxxxxxxxxxx
tis UNIX timestamp in hex digit
Or in binary representation, the 128-bit sequential UUIDv4 consists of five segments:
[unixtime:32][random:16]['4':4][random:12]['2'(first two bits of `y`):2][random:62]
Implementation in Elixir
Thanks to binary pattern matching. The implementation in Elixir is trivial.
defmodule SeqUUIDv4 do
def generate() do
unix_time = DateTime.utc_now() |> DateTime.to_unix()
<<_r0::32, r1::16, _r2::4, r3::12, _r4::2, r5::62>> = :crypto.strong_rand_bytes(16)
<<unix_time::32, r1::16, 4::4, r3::12, 2::2, r5::62>>
end
end
The output of generate/0 is binary.
To encode as hex numbers use Base.encode16/1:
SeqUUIDv4.generate() |> Base.encode16()