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.
x
is any random hexadecimal digity
is either8
,9
,A
, orB
4
andy
are version flags indicate version 4 UUID 2y
is 4 bit:10zz
wherez
is random bit. Hence, the possible value ofy
is1000
(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
t
is 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()