// Copyright 2018 Google Inc. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package uuidimport ()// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC// 4122.typeUUID [16]byte// A Version represents a UUID's version.typeVersionbyte// A Variant represents a UUID's variant.typeVariantbyte// Constants returned by Variant.const (Invalid = Variant(iota) // Invalid UUIDRFC4122// The variant specified in RFC4122Reserved// Reserved, NCS backward compatibility.Microsoft// Reserved, Microsoft Corporation backward compatibility.Future// Reserved for future definition.)const randPoolSize = 16 * 16var ( rander = rand.Reader// random function poolEnabled = false poolMu sync.Mutex poolPos = randPoolSize// protected with poolMu pool [randPoolSize]byte// protected with poolMu)type invalidLengthError struct{ len int }func ( invalidLengthError) () string {returnfmt.Sprintf("invalid UUID length: %d", .len)}// IsInvalidLengthError is matcher function for custom error invalidLengthErrorfunc ( error) bool { , := .(invalidLengthError)return}// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both// the standard UUID forms defined in RFC 4122// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition,// Parse accepts non-standard strings such as the raw hex encoding// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings,// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are// examined in the latter case. Parse should not be used to validate strings as// it parses non-standard encodings as indicated above.func ( string) (UUID, error) {varUUIDswitchlen() {// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxcase36:// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxcase36 + 9:if !strings.EqualFold([:9], "urn:uuid:") {return , fmt.Errorf("invalid urn prefix: %q", [:9]) } = [9:]// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}case36 + 2: = [1:]// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcase32:varboolfor := range { [], = xtob([*2], [*2+1])if ! {return , errors.New("invalid UUID format") } }return , nildefault:return , invalidLengthError{len()} }// s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxif [8] != '-' || [13] != '-' || [18] != '-' || [23] != '-' {return , errors.New("invalid UUID format") }for , := range [16]int{0, 2, 4, 6,9, 11,14, 16,19, 21,24, 26, 28, 30, 32, 34, } { , := xtob([], [+1])if ! {return , errors.New("invalid UUID format") } [] = }return , nil}// ParseBytes is like Parse, except it parses a byte slice instead of a string.func ( []byte) (UUID, error) {varUUIDswitchlen() {case36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxcase36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxif !bytes.EqualFold([:9], []byte("urn:uuid:")) {return , fmt.Errorf("invalid urn prefix: %q", [:9]) } = [9:]case36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} = [1:]case32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvarboolfor := 0; < 32; += 2 { [/2], = xtob([], [+1])if ! {return , errors.New("invalid UUID format") } }return , nildefault:return , invalidLengthError{len()} }// s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxif [8] != '-' || [13] != '-' || [18] != '-' || [23] != '-' {return , errors.New("invalid UUID format") }for , := range [16]int{0, 2, 4, 6,9, 11,14, 16,19, 21,24, 26, 28, 30, 32, 34, } { , := xtob([], [+1])if ! {return , errors.New("invalid UUID format") } [] = }return , nil}// MustParse is like Parse but panics if the string cannot be parsed.// It simplifies safe initialization of global variables holding compiled UUIDs.func ( string) UUID { , := Parse()if != nil {panic(`uuid: Parse(` + + `): ` + .Error()) }return}// FromBytes creates a new UUID from a byte slice. Returns an error if the slice// does not have a length of 16. The bytes are copied from the slice.func ( []byte) ( UUID, error) { = .UnmarshalBinary()return , }// Must returns uuid if err is nil and panics otherwise.func ( UUID, error) UUID {if != nil {panic() }return}// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx// , or "" if uuid is invalid.func ( UUID) () string {var [36]byteencodeHex([:], )returnstring([:])}// URN returns the RFC 2141 URN form of uuid,// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.func ( UUID) () string {var [36 + 9]bytecopy([:], "urn:uuid:")encodeHex([9:], )returnstring([:])}func encodeHex( []byte, UUID) {hex.Encode(, [:4]) [8] = '-'hex.Encode([9:13], [4:6]) [13] = '-'hex.Encode([14:18], [6:8]) [18] = '-'hex.Encode([19:23], [8:10]) [23] = '-'hex.Encode([24:], [10:])}// Variant returns the variant encoded in uuid.func ( UUID) () Variant {switch {case ([8] & 0xc0) == 0x80:returnRFC4122case ([8] & 0xe0) == 0xc0:returnMicrosoftcase ([8] & 0xe0) == 0xe0:returnFuturedefault:returnReserved }}// Version returns the version of uuid.func ( UUID) () Version {returnVersion([6] >> 4)}func ( Version) () string {if > 15 {returnfmt.Sprintf("BAD_VERSION_%d", ) }returnfmt.Sprintf("VERSION_%d", )}func ( Variant) () string {switch {caseRFC4122:return"RFC4122"caseReserved:return"Reserved"caseMicrosoft:return"Microsoft"caseFuture:return"Future"caseInvalid:return"Invalid" }returnfmt.Sprintf("BadVariant%d", int())}// SetRand sets the random number generator to r, which implements io.Reader.// If r.Read returns an error when the package requests random data then// a panic will be issued.//// Calling SetRand with nil sets the random number generator to the default// generator.func ( io.Reader) {if == nil {rander = rand.Readerreturn }rander = }// EnableRandPool enables internal randomness pool used for Random// (Version 4) UUID generation. The pool contains random bytes read from// the random number generator on demand in batches. Enabling the pool// may improve the UUID generation throughput significantly.//// Since the pool is stored on the Go heap, this feature may be a bad fit// for security sensitive applications.//// Both EnableRandPool and DisableRandPool are not thread-safe and should// only be called when there is no possibility that New or any other// UUID Version 4 generation function will be called concurrently.func () {poolEnabled = true}// DisableRandPool disables the randomness pool if it was previously// enabled with EnableRandPool.//// Both EnableRandPool and DisableRandPool are not thread-safe and should// only be called when there is no possibility that New or any other// UUID Version 4 generation function will be called concurrently.func () {poolEnabled = falsedeferpoolMu.Unlock()poolMu.Lock()poolPos = randPoolSize}// UUIDs is a slice of UUID types.typeUUIDs []UUID// Strings returns a string slice containing the string form of each UUID in uuids.func ( UUIDs) () []string {var = make([]string, len())for , := range { [] = .String() }return}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.