Source File
uuid.go
Belonging Package
uuid
// Copyright 2026 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// Package uuid provides support for generating and manipulating UUIDs.//// See [RFC 9562] for details.//// Random components of new UUIDs are generated with a// cryptographically secure random number generator.//// UUIDs may be generated using various algorithms.// The [New] function returns a new UUID generated using// an algorithm suitable for most purposes.//// [RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562.htmlpackage uuidimport ()// A UUID is a Universally Unique Identifier as specified in RFC 9562.//// UUIDs are comparable, such as with the == operator.type UUID [16]byte// Parse returns the UUID represented by s.//// It accepts strings in the following forms://// f81d4fae-7dec-11d0-a765-00a0c91e6bf6// {f81d4fae-7dec-11d0-a765-00a0c91e6bf6}// urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6// f81d4fae7dec11d0a76500a0c91e6bf6//// Alphabetic characters in the hexadecimal digits may be any case.func ( string) (UUID, error) {var UUID:= .UnmarshalText([]byte())return ,}// MustParse returns the UUID represented by s.//// It panics if s is not a valid string representation of a UUID as defined by [Parse].func ( string) UUID {, := Parse()if != nil {panic()}return}// New returns a new UUID.//// Programs which do not have a need for a specific UUID generation algorithm should use New.// At this time, New is equivalent to [NewV4].func () UUID {return NewV4()}// Nil returns the Nil UUID 00000000-0000-0000-0000-000000000000.//// The Nil UUID is defined in [Section 5.9 of RFC 9562].// Note that this is not the same as the Go value nil.//// [Section 5.9 of RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562#section-5.9func () UUID {return UUID{}}// Max returns the Max UUID ffffffff-ffff-ffff-ffff-ffffffffffff.//// The Max UUID is defined in [Section 5.10 of RFC 9562].//// [Section 5.10 of RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562#section-5.10func () UUID {return UUID{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,}}// String returns the string representation of u.//// It uses the lowercase hex-and-dash representation defined in RFC 9562.func ( UUID) () string {, := .MarshalText()return string()}// MarshalText implements the [encoding.TextMarshaler] interface.// The encoding is the same as returned by [UUID.String]func ( UUID) () ([]byte, error) {return .AppendText(make([]byte, 0, 36))}// AppendText implements the [encoding.TextAppender] interface.// The encoding is the same as returned by [UUID.String]func ( UUID) ( []byte) ([]byte, error) {:= len()= append(, "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"...):= [:]hex.Encode([0:8], [0:4])hex.Encode([9:13], [4:6])hex.Encode([14:18], [6:8])hex.Encode([19:23], [8:10])hex.Encode([24:36], [10:16])return , nil}var errInvalid = errors.New("invalid uuid")// UnmarshalText implements the [encoding.TextUnmarshaler] interface.// The UUID is expected in a form accepted by [Parse].func ( *UUID) ( []byte) error {var UUIDswitch len() {case len("urn:uuid:") + 36:// urn:uuid:00000000-0000-0000-0000-000000000000= bytes.TrimPrefix(, []byte("urn:uuid:"))case 2 + 36:// {00000000-0000-0000-0000-000000000000}= bytes.TrimPrefix(, []byte("{"))= bytes.TrimSuffix(, []byte("}"))case 32:// 00000000000000000000000000000000if , := hex.Decode([:], ); != nil {return errInvalid}* =return nil}// 00000000-0000-0000-0000-000000000000if len() != 36 {return errInvalid}if [8] != '-' || [13] != '-' || [18] != '-' || [23] != '-' {return errInvalid}if , := hex.Decode([0:4], [0:8]); != nil {return errInvalid}if , := hex.Decode([4:6], [9:13]); != nil {return errInvalid}if , := hex.Decode([6:8], [14:18]); != nil {return errInvalid}if , := hex.Decode([8:10], [19:23]); != nil {return errInvalid}if , := hex.Decode([10:16], [24:36]); != nil {return errInvalid}* =return nil}// Compare compares the UUID u with v.// If u is before v, it returns -1.// If u is after v, it returns +1.// If they are the same, it returns 0.//// Compare uses the big-endian byte order defined in// [Section 6.11 of RFC 9562] for sorting.//// [Section 6.11 of RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562#section-6.11func ( UUID) ( UUID) int {for := range {if := cmp.Compare([], []); != 0 {return}}return 0}// NewV4 returns a new version 4 UUID.//// Version 4 UUIDs contain 122 bits of random data.func () UUID {var UUIDrand.Read([:]).setVersion(4).setVariant(0b10)return}var (v7mu sync.Mutexv7lastSecs uint64v7lastTimestamp uint64)// NewV7 returns a new version 7 UUID.//// Version 7 UUIDs contain a timestamp in the most significant 48 bits,// and at least 62 bits of random data.//// NewV7 always returns UUIDs which sort in increasing order,// except when the system clock moves backwards.func () UUID {// UUIDv7 is defined in RFC 9562 section 5.7 as://// 0 1 2 3// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+// | unix_ts_ms |// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+// | unix_ts_ms | ver | rand_a |// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+// |var| rand_b |// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+// | rand_b |// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//// We store a 12 bit sub-millisecond timestamp fraction in the rand_a section,// as optionally permitted by the RFC.v7mu.Lock()// Generate our 60-bit timestamp: 48 bits of millisecond-resolution,// followed by 12 bits of 1/4096-millisecond resolution.:= time.Now():= uint64(.Unix()):= uint64(.Nanosecond()):= / 1000000:= - (1000000 * ):= (1000* + ) << 12 // ms shifted into position+= ( * 4096) / 1000000 // ns converted to 1/4096-ms unitsif v7lastSecs > {// Time has gone backwards.// This presumably indicates the system clock has changed.// Ignore previously-generated UUIDs.} else if <= v7lastTimestamp {// This timestamp is the same as a previously-generated UUID.// To preserve the property that we generate UUIDs in order,// use a timestamp 1/4096 millisecond later than the most recently// generated UUID.= v7lastTimestamp + 1}v7lastSecs =v7lastTimestamp =v7mu.Unlock()// Insert a gap for the 4 bits of the ver field into the timestamp.:= (( << 4) & 0xffff_ffff_ffff_0000) | ( & 0x0ffff)var UUIDbinary.BigEndian.PutUint64([0:8], )rand.Read([8:]).setVersion(7).setVariant(0b10)return}func ( *UUID) ( byte) {[6] = ([6] & 0b0000_1111) | ( << 4)}func ( *UUID) ( byte) {[8] = ([8] & 0b0011_1111) | ( << 6)}
The pages are generated with Golds v0.8.4. (GOOS=linux GOARCH=amd64)