Skip to content

Commit

Permalink
Add uuid_v7 support
Browse files Browse the repository at this point in the history
UUIDv7, currently RFC is a new version that allows for time
ordering thanks to a unix timestamp component.

@see https://datatracker.ietf.org/doc/draft-peabody-dispatch-new-uuid-format/04/
  • Loading branch information
khasinski committed Nov 2, 2022
1 parent fbce06e commit 8e36c6a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lib/random/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,28 @@ def uuid
"%08x-%04x-%04x-%04x-%04x%08x" % ary
end

# Random::Formatter#uuid generates a random v7 UUID (Universally Unique IDentifier).
#
# require 'random/formatter'
#
# prng.uuid_v7 #=> "67fd173a-8401-7654-b51a-7654b702351a"
# prng.uuid_v7 #=> "67fd173a-8401-7bb0-9f7e-0bb063b7df7e"
# prng.uuid_v7 #=> "6bfd173a-8401-7eb0-bb89-4eb0e36a7b89"
#
# The version 7 UUID is random, but contains a time-based part for order (except the version).
#
# The result contains 122 random bits (15.25 random bytes).
#
# See RFC 4122 for details of UUID.
#
def uuid_v7
ts = [Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond)].pack('Q').unpack('Nn')
ary = random_bytes(10).unpack("nnnN")
ary[0] = (ary[2] & 0x0fff) | 0x7000
ary[1] = (ary[3] & 0x3fff) | 0x8000
"%08x-%04x-%04x-%04x-%04x%08x" % (ts + ary)
end

private def gen_random(n)
self.bytes(n)
end
Expand Down
11 changes: 11 additions & 0 deletions test/ruby/test_random_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ def test_uuid
assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
end

def test_uuid_v7
uuid = @it.uuid_v7
assert_equal(36, uuid.size)

# Check time_hi_and_version and clock_seq_hi_res bits (RFC 4122 4.4)
assert_equal('7', uuid[14])
assert_include(%w'8 9 a b', uuid[19])

assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
end

def test_alphanumeric
65.times do |n|
an = @it.alphanumeric(n)
Expand Down

0 comments on commit 8e36c6a

Please sign in to comment.