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 digit
- yis either- 8,- 9,- A, or- B
- 4and- yare version flags indicate version 4 UUID 2- yis 4 bit:- 10zzwhere- zis random bit. Hence, the possible value of- yis- 1000(- 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()