Documentation
¶
Overview ¶
Package uuid implements UUID generation and parsing per RFC 9562.
Supported versions:
- V4 (Random): most common
- V5 (SHA-1 name-based): deterministic, canonical IDs
- V7 (Unix timestamp + random): recommended for new systems
- V8 (Custom/experimental): user-provided data with version+variant bits
UUID is a 16-byte value type that is comparable and safe for use as a map key. The zero value is the Nil UUID (all zeros).
Generation ¶
Stateless functions require no configuration:
id := uuid.NewV4() // random id := uuid.NewV5(uuid.NamespaceDNS, "example") // deterministic (SHA-1)
For V7 UUIDs with per-instance monotonicity, use a Generator:
gen := uuid.NewGenerator() id := gen.NewV7()
A package-level convenience function is also available:
id := uuid.NewV7()
Parsing ¶
Parse is strict: it only accepts the standard 36-character hyphenated form. ParseLenient additionally accepts URN, braced, and compact (32-hex) forms.
id, err := uuid.Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
id, err := uuid.ParseLenient("urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8")
SQL NULL handling ¶
Instead of a separate NullUUID type, use a *UUID pointer:
var id *uuid.UUID // nil = SQL NULL
Index ¶
- Variables
- func Compare(a, b UUID) int
- type Generator
- type LengthError
- type ParseError
- type Pool
- type UUID
- func FromBytes(b []byte) (UUID, error)
- func MustParse(s string) UUID
- func NewV4() UUID
- func NewV4Batch(n int) []UUID
- func NewV5(namespace UUID, name string) UUID
- func NewV7() UUID
- func NewV7Batch(n int) []UUID
- func NewV8(data [16]byte) UUID
- func Parse(s string) (UUID, error)
- func ParseLenient(s string) (UUID, error)
- func (u UUID) AppendBinary(b []byte) ([]byte, error)
- func (u UUID) AppendText(b []byte) ([]byte, error)
- func (u UUID) Bytes() []byte
- func (u UUID) IsNil() bool
- func (u UUID) MarshalBinary() ([]byte, error)
- func (u UUID) MarshalText() ([]byte, error)
- func (u *UUID) Scan(src any) error
- func (u UUID) String() string
- func (u UUID) Time() time.Time
- func (u UUID) URN() string
- func (u *UUID) UnmarshalBinary(data []byte) error
- func (u *UUID) UnmarshalText(data []byte) error
- func (u UUID) Value() (driver.Value, error)
- func (u UUID) Variant() Variant
- func (u UUID) Version() Version
- type Variant
- type Version
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( NamespaceDNS = UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} NamespaceURL = UUID{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} NamespaceOID = UUID{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} NamespaceX500 = UUID{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} )
RFC 9562 Appendix C pre-defined namespace UUIDs.
var Max = UUID{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
}
Max is the maximum UUID (all 0xFF bytes), defined in RFC 9562 Section 5.10.
Functions ¶
func Compare ¶
Compare returns an integer comparing two UUIDs lexicographically. The result is 0 if a == b, -1 if a < b, and +1 if a > b. This is suitable for use with slices.SortFunc.
Example ¶
package main
import (
"fmt"
"slices"
"github.com/pscheid92/uuid"
)
func main() {
ids := []uuid.UUID{
uuid.MustParse("00000000-0000-0000-0000-000000000003"),
uuid.MustParse("00000000-0000-0000-0000-000000000001"),
uuid.MustParse("00000000-0000-0000-0000-000000000002"),
}
slices.SortFunc(ids, uuid.Compare)
for _, id := range ids {
fmt.Println(id)
}
}
Output: 00000000-0000-0000-0000-000000000001 00000000-0000-0000-0000-000000000002 00000000-0000-0000-0000-000000000003
Types ¶
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator produces Version 7 UUIDs with per-instance monotonicity. Multiple goroutines may safely call NewV7 concurrently on the same Generator.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
gen := uuid.NewGenerator()
id := gen.NewV7()
fmt.Println(id.Version())
}
Output: V7
func NewGenerator ¶
func NewGenerator() *Generator
NewGenerator returns a new V7 UUID generator with its own monotonicity state.
func (*Generator) NewV7 ¶
NewV7 returns a new Version 7 UUID.
The UUID encodes a 48-bit Unix millisecond timestamp in bits 0–47 and 12 bits of sub-millisecond precision in the rand_a field (bits 48–59), computed per RFC 9562 Section 6.2 Method 3. The rand_b field (bytes 8–15, bits 64–127) is filled with random data from crypto/rand.
When multiple UUIDs are generated faster than the clock resolution, the combined timestamp+seq counter is incremented to guarantee monotonicity within this Generator. Counter increments can carry into the millisecond field, so under sustained bursts the encoded timestamp (and thus UUID.Time) may run slightly ahead of the wall clock.
func (*Generator) NewV7Batch ¶
NewV7Batch returns n Version 7 UUIDs that are monotonically increasing. It amortizes the cost of crypto/rand and time.Now by performing a single call of each, making it significantly faster than calling Generator.NewV7 in a loop. It returns nil if n <= 0.
All n UUIDs derive from one clock reading: consecutive counter values can carry into the millisecond field, so for large n the encoded timestamps may run slightly ahead of the wall clock.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
gen := uuid.NewGenerator()
ids := gen.NewV7Batch(3)
fmt.Println(len(ids))
fmt.Println(ids[0].Version())
}
Output: 3 V7
type LengthError ¶
type LengthError struct {
Got int // the actual length
Want string // description of expected length
}
LengthError is returned when the input has an unexpected byte length.
Use errors.AsType to check for this error:
if lerr, ok := errors.AsType[*LengthError](err); ok {
fmt.Println(lerr.Got, lerr.Want)
}
func (*LengthError) Error ¶
func (e *LengthError) Error() string
type ParseError ¶
type ParseError struct {
Input string // the string that failed to parse, truncated to 64 bytes if longer
Msg string // description of the problem
}
ParseError is returned when a UUID string cannot be parsed.
Use errors.AsType to check for this error:
if perr, ok := errors.AsType[*ParseError](err); ok {
fmt.Println(perr.Input)
}
func (*ParseError) Error ¶
func (e *ParseError) Error() string
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool amortizes the cost of crypto/rand by pre-generating random bytes in bulk. It provides high-throughput Pool.NewV4 and Pool.NewV7 methods that are functionally equivalent to the package-level functions. Multiple goroutines may safely call methods concurrently.
Because Pool buffers pre-generated randomness in process memory, it is not fork-safe: a forked process or a cloned/restored VM snapshot can duplicate the buffer, causing both copies to emit identical UUIDs. Use the package-level functions where fork or VM-clone safety matters.
func (*Pool) NewV4 ¶
NewV4 returns a new random (Version 4) UUID from the pool. It is functionally equivalent to the package-level NewV4 but amortizes the crypto/rand overhead across pool refills.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
pool := uuid.NewPool()
id := pool.NewV4()
fmt.Println(id.Version())
}
Output: V4
func (*Pool) NewV7 ¶
NewV7 returns a new Version 7 UUID from the pool. It is functionally equivalent to Generator.NewV7 but amortizes the crypto/rand overhead by buffering random bytes for the rand_b field. Timestamps are computed live to remain accurate, though under sustained bursts they may run slightly ahead of the wall clock (see Generator.NewV7).
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
pool := uuid.NewPool()
id := pool.NewV7()
fmt.Println(id.Version())
}
Output: V7
type UUID ¶
type UUID [16]byte
UUID is a 128-bit universally unique identifier per RFC 9562. It is a value type: comparable, copyable, and safe for use as a map key.
var Nil UUID
Nil is the zero-value UUID (all zeros).
func FromBytes ¶
FromBytes creates a UUID from a 16-byte slice.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
b := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
id, err := uuid.FromBytes(b)
if err != nil {
panic(err)
}
fmt.Println(id)
}
Output: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
func MustParse ¶
MustParse is like Parse but panics if the string cannot be parsed. It simplifies initialization of global variables holding UUIDs.
func NewV4 ¶
func NewV4() UUID
NewV4 returns a new random (Version 4) UUID. It reads from crypto/rand which cannot fail on Go 1.26+.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
id := uuid.NewV4()
fmt.Println(id.Version())
}
Output: V4
func NewV4Batch ¶
NewV4Batch returns n random (Version 4) UUIDs. It amortizes the cost of crypto/rand by reading all random bytes in a single call, making it significantly faster than calling NewV4 in a loop. It returns nil if n <= 0.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
ids := uuid.NewV4Batch(3)
fmt.Println(len(ids))
fmt.Println(ids[0].Version())
}
Output: 3 V4
func NewV5 ¶
NewV5 returns a deterministic Version 5 (SHA-1) UUID for the given namespace and name.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
id := uuid.NewV5(uuid.NamespaceDNS, "www.example.com")
fmt.Println(id)
}
Output: 2ed6657d-e927-568b-95e1-2665a8aea6a2
func NewV7 ¶
func NewV7() UUID
NewV7 returns a new Version 7 (Unix timestamp + random) UUID using the package-level default generator. For isolated monotonicity guarantees, create a dedicated Generator with NewGenerator.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
id := uuid.NewV7()
fmt.Println(id.Version())
}
Output: V7
func NewV7Batch ¶ added in v0.3.0
NewV7Batch returns n monotonically increasing Version 7 UUIDs using the package-level default generator. See Generator.NewV7Batch.
func NewV8 ¶
NewV8 returns a Version 8 UUID constructed from user-provided data. The version and variant bits are set; all other 122 bits come from data. Uniqueness is the caller's responsibility per RFC 9562 Section 5.8.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
var data [16]byte
copy(data[:], "custom-data-here")
id := uuid.NewV8(data)
fmt.Println(id.Version())
}
Output: V8
func Parse ¶
Parse parses a UUID from the standard 36-character hyphenated form: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
For URN, braced, or compact (32-hex) forms, use ParseLenient.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
id, err := uuid.Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
panic(err)
}
fmt.Println(id)
}
Output: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
func ParseLenient ¶
ParseLenient parses a UUID from any of these forms:
- Standard: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (36 chars)
- URN: urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (45 chars)
- Braced: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (38 chars)
- Compact: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 chars)
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
// Accepts URN, braced, and compact forms in addition to standard
id, err := uuid.ParseLenient("urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
panic(err)
}
fmt.Println(id)
}
Output: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
func (UUID) AppendBinary ¶
AppendBinary appends the raw 16-byte representation of u to b. It implements encoding.BinaryAppender.
func (UUID) AppendText ¶
AppendText appends the textual (36-char hyphenated) representation of u to b. It implements encoding.TextAppender.
func (UUID) MarshalBinary ¶
MarshalBinary returns the raw 16-byte representation. It implements encoding.BinaryMarshaler.
func (UUID) MarshalText ¶
MarshalText returns the 36-character hyphenated representation. It implements encoding.TextMarshaler. JSON encoding uses this method automatically.
func (*UUID) Scan ¶
Scan implements database/sql.Scanner. It supports scanning from:
- string: 16 raw bytes (e.g. a BINARY(16) column delivered as string) or text form parsed with ParseLenient
- []byte: 16 raw bytes or text form parsed with ParseLenient
Scanning SQL NULL is an error; use *UUID (nil pointer = NULL) instead.
func (UUID) String ¶
String returns the standard 36-character hyphenated UUID representation: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
func (UUID) Time ¶
Time extracts the millisecond-precision Unix timestamp from a V7 UUID. For non-V7 UUIDs, the returned time is meaningless.
For V7 UUIDs generated by this package under sustained bursts, the timestamp may be marginally ahead of the actual creation time due to the monotonic counter (see Generator.NewV7).
func (UUID) URN ¶
URN returns the UUID in URN form: urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Example ¶
package main
import (
"fmt"
"github.com/pscheid92/uuid"
)
func main() {
id := uuid.MustParse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
fmt.Println(id.URN())
}
Output: urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8
func (*UUID) UnmarshalBinary ¶
UnmarshalBinary sets u from a 16-byte slice. It implements encoding.BinaryUnmarshaler.
func (*UUID) UnmarshalText ¶
UnmarshalText parses a UUID from text (strict 36-char format). It implements encoding.TextUnmarshaler.
func (UUID) Value ¶
Value implements database/sql/driver.Valuer. It returns the UUID as a 36-character string.
type Variant ¶
type Variant uint8
Variant represents the UUID variant field.