std/uuid
import std/uuid to use it. Source: src/std/uuid.iyi at v0.18.0.
UUID.v4 is 122 random bits with version 4 and the RFC variant bits; UUID.v7 is the Unix time in milliseconds in its first 48 bits, then version 7, then random bits, so that UUIDs made later sort later - the kind a database index wants as a key. Every random bit comes from Random::Secure, the operating system's entropy: a UUID is often a name nobody else may guess, and the PCG generator v4 drew from before is built for speed, not to keep its state from someone reading it.
Either answers the hyphenated form through to_s; parse reads it back, or the 32 digits with no hyphens, and panics on a length, hyphen or hex digit that is not one.
UUIDstruct
pub struct UUID
def ==(other : UUID) : Bool
def bytes : Array(UInt8)
# Hashing follows `==`: the sixteen bytes, as an array of them hashes.
# Without it every UUID hashed to its type, so the all-zero and the all-f
# UUIDs hashed alike and a table of 16,000 UUID keys took 2.0 s to fill
# where the same UUIDs as strings took 5 ms.
def hash : Int32
# The sixteen bytes are the UUID's own, copied in here and out of
# `bytes`, as the other library's are a value: held as the caller's
# array, a buffer reused for the next record changed every UUID made
# from it (`b[0] = 255_u8` after `UUID.new(b)` turned `00000000-...`
# into `ff000000-...`), and `u.bytes[1] = 255_u8` changed a UUID that
# was already a hash key, which its table then could not find.
def initialize(bytes : Array(UInt8))
def self.parse(text : String) : UUID
protected def stored : Array(UInt8)
def to_s : String
# Sixteen bytes from the operating system, six bits of them then set to
# say version 4 and the RFC variant. Drawn from `Random.new`, they were
# sixteen outputs of a fresh PCG generator: every UUID was a function of
# the generator's 127 bits of state, and PCG makes no promise that its
# outputs do not give that state away, where a version 4 UUID promises
# 122 bits nobody can predict.
def self.v4 : UUID
# RFC 9562 version 7: 48 bits of Unix milliseconds, big-endian, then the
# version, 12 bits of `rand_a`, the variant and 62 random bits.
#
# Two UUIDs from one millisecond would sort at random by their random
# bits, so `rand_a` is a counter here (the RFC's "fixed bit-length
# dedicated counter", section 6.2 method 1): a new millisecond starts it
# at a random 11 bits, leaving at least 2,048 steps before it runs out,
# and every UUID in the same millisecond, or one the clock stepped back
# into, counts one up from the last. Past 4,095 the stamp moves on a
# millisecond early, as the RFC allows. Each UUID this process makes
# therefore sorts after the one before it, as bytes and as text; the
# 62 bits after the counter are random every time, so two processes in
# one millisecond still do not collide.
def self.v7 : UUID
def version : Int32
end
UUIDs, RFC 9562 (which replaced RFC 4122), written in iyi.