// 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.html
package uuid import ( ) // 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.9 func () 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.10 func () 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 UUID switch 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: // 00000000000000000000000000000000 if , := hex.Decode([:], ); != nil { return errInvalid } * = return nil } // 00000000-0000-0000-0000-000000000000 if 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.11 func ( 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 UUID rand.Read([:]) .setVersion(4) .setVariant(0b10) return } var ( v7mu sync.Mutex v7lastSecs uint64 v7lastTimestamp 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 units if 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 UUID binary.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) }