pax_global_header00006660000000000000000000000064140731415200014507gustar00rootroot0000000000000052 comment=44b5fee7c49cf3bcdf723f106b36d56ef13ccc88 uuid-1.3.0/000077500000000000000000000000001407314152000124565ustar00rootroot00000000000000uuid-1.3.0/.travis.yml000066400000000000000000000001141407314152000145630ustar00rootroot00000000000000language: go go: - 1.4.3 - 1.5.3 - tip script: - go test -v ./... uuid-1.3.0/CONTRIBUTING.md000066400000000000000000000004701407314152000147100ustar00rootroot00000000000000# How to contribute We definitely welcome patches and contribution to this project! ### Legal requirements In order to protect both you and ourselves, you will need to sign the [Contributor License Agreement](https://cla.developers.google.com/clas). You may have already signed it for other Google projects. uuid-1.3.0/CONTRIBUTORS000066400000000000000000000001511407314152000143330ustar00rootroot00000000000000Paul Borman bmatsuo shawnps theory jboverfelt dsymonds cd1 wallclockbuilder dansouza uuid-1.3.0/LICENSE000066400000000000000000000027101407314152000134630ustar00rootroot00000000000000Copyright (c) 2009,2014 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. uuid-1.3.0/README.md000066400000000000000000000015601407314152000137370ustar00rootroot00000000000000# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services. This package is based on the github.com/pborman/uuid package (previously named code.google.com/p/go-uuid). It differs from these earlier packages in that a UUID is a 16 byte array rather than a byte slice. One loss due to this change is the ability to represent an invalid UUID (vs a NIL UUID). ###### Install `go get github.com/google/uuid` ###### Documentation [![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: http://pkg.go.dev/github.com/google/uuid uuid-1.3.0/dce.go000066400000000000000000000040301407314152000135350ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "encoding/binary" "fmt" "os" ) // A Domain represents a Version 2 domain type Domain byte // Domain constants for DCE Security (Version 2) UUIDs. const ( Person = Domain(0) Group = Domain(1) Org = Domain(2) ) // NewDCESecurity returns a DCE Security (Version 2) UUID. // // The domain should be one of Person, Group or Org. // On a POSIX system the id should be the users UID for the Person // domain and the users GID for the Group. The meaning of id for // the domain Org or on non-POSIX systems is site defined. // // For a given domain/id pair the same token may be returned for up to // 7 minutes and 10 seconds. func NewDCESecurity(domain Domain, id uint32) (UUID, error) { uuid, err := NewUUID() if err == nil { uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 uuid[9] = byte(domain) binary.BigEndian.PutUint32(uuid[0:], id) } return uuid, err } // NewDCEPerson returns a DCE Security (Version 2) UUID in the person // domain with the id returned by os.Getuid. // // NewDCESecurity(Person, uint32(os.Getuid())) func NewDCEPerson() (UUID, error) { return NewDCESecurity(Person, uint32(os.Getuid())) } // NewDCEGroup returns a DCE Security (Version 2) UUID in the group // domain with the id returned by os.Getgid. // // NewDCESecurity(Group, uint32(os.Getgid())) func NewDCEGroup() (UUID, error) { return NewDCESecurity(Group, uint32(os.Getgid())) } // Domain returns the domain for a Version 2 UUID. Domains are only defined // for Version 2 UUIDs. func (uuid UUID) Domain() Domain { return Domain(uuid[9]) } // ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 // UUIDs. func (uuid UUID) ID() uint32 { return binary.BigEndian.Uint32(uuid[0:4]) } func (d Domain) String() string { switch d { case Person: return "Person" case Group: return "Group" case Org: return "Org" } return fmt.Sprintf("Domain%d", int(d)) } uuid-1.3.0/doc.go000066400000000000000000000006271407314152000135570ustar00rootroot00000000000000// Copyright 2016 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 uuid generates and inspects UUIDs. // // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security // Services. // // A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to // maps or compared directly. package uuid uuid-1.3.0/go.mod000066400000000000000000000000361407314152000135630ustar00rootroot00000000000000module github.com/google/uuid uuid-1.3.0/hash.go000066400000000000000000000033341407314152000137330ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "crypto/md5" "crypto/sha1" "hash" ) // Well known namespace IDs and UUIDs var ( NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) Nil UUID // empty UUID, all zeros ) // NewHash returns a new UUID derived from the hash of space concatenated with // data generated by h. The hash should be at least 16 byte in length. The // first 16 bytes of the hash are used to form the UUID. The version of the // UUID will be the lower 4 bits of version. NewHash is used to implement // NewMD5 and NewSHA1. func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { h.Reset() h.Write(space[:]) //nolint:errcheck h.Write(data) //nolint:errcheck s := h.Sum(nil) var uuid UUID copy(uuid[:], s) uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant return uuid } // NewMD5 returns a new MD5 (Version 3) UUID based on the // supplied name space and data. It is the same as calling: // // NewHash(md5.New(), space, data, 3) func NewMD5(space UUID, data []byte) UUID { return NewHash(md5.New(), space, data, 3) } // NewSHA1 returns a new SHA1 (Version 5) UUID based on the // supplied name space and data. It is the same as calling: // // NewHash(sha1.New(), space, data, 5) func NewSHA1(space UUID, data []byte) UUID { return NewHash(sha1.New(), space, data, 5) } uuid-1.3.0/json_test.go000066400000000000000000000023341407314152000150170ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "encoding/json" "reflect" "testing" ) var testUUID = Must(Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")) func TestJSON(t *testing.T) { type S struct { ID1 UUID ID2 UUID } s1 := S{ID1: testUUID} data, err := json.Marshal(&s1) if err != nil { t.Fatal(err) } var s2 S if err := json.Unmarshal(data, &s2); err != nil { t.Fatal(err) } if !reflect.DeepEqual(&s1, &s2) { t.Errorf("got %#v, want %#v", s2, s1) } } func BenchmarkUUID_MarshalJSON(b *testing.B) { x := &struct { UUID UUID `json:"uuid"` }{} var err error x.UUID, err = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") if err != nil { b.Fatal(err) } for i := 0; i < b.N; i++ { js, err := json.Marshal(x) if err != nil { b.Fatalf("marshal json: %#v (%v)", js, err) } } } func BenchmarkUUID_UnmarshalJSON(b *testing.B) { js := []byte(`{"uuid":"f47ac10b-58cc-0372-8567-0e02b2c3d479"}`) var x *struct { UUID UUID `json:"uuid"` } for i := 0; i < b.N; i++ { err := json.Unmarshal(js, &x) if err != nil { b.Fatalf("marshal json: %#v (%v)", js, err) } } } uuid-1.3.0/marshal.go000066400000000000000000000016131407314152000144350ustar00rootroot00000000000000// Copyright 2016 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 uuid import "fmt" // MarshalText implements encoding.TextMarshaler. func (uuid UUID) MarshalText() ([]byte, error) { var js [36]byte encodeHex(js[:], uuid) return js[:], nil } // UnmarshalText implements encoding.TextUnmarshaler. func (uuid *UUID) UnmarshalText(data []byte) error { id, err := ParseBytes(data) if err != nil { return err } *uuid = id return nil } // MarshalBinary implements encoding.BinaryMarshaler. func (uuid UUID) MarshalBinary() ([]byte, error) { return uuid[:], nil } // UnmarshalBinary implements encoding.BinaryUnmarshaler. func (uuid *UUID) UnmarshalBinary(data []byte) error { if len(data) != 16 { return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) } copy(uuid[:], data) return nil } uuid-1.3.0/node.go000066400000000000000000000044231407314152000137350ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "sync" ) var ( nodeMu sync.Mutex ifname string // name of interface being used nodeID [6]byte // hardware for version 1 UUIDs zeroID [6]byte // nodeID with only 0's ) // NodeInterface returns the name of the interface from which the NodeID was // derived. The interface "user" is returned if the NodeID was set by // SetNodeID. func NodeInterface() string { defer nodeMu.Unlock() nodeMu.Lock() return ifname } // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. // If name is "" then the first usable interface found will be used or a random // Node ID will be generated. If a named interface cannot be found then false // is returned. // // SetNodeInterface never fails when name is "". func SetNodeInterface(name string) bool { defer nodeMu.Unlock() nodeMu.Lock() return setNodeInterface(name) } func setNodeInterface(name string) bool { iname, addr := getHardwareInterface(name) // null implementation for js if iname != "" && addr != nil { ifname = iname copy(nodeID[:], addr) return true } // We found no interfaces with a valid hardware address. If name // does not specify a specific interface generate a random Node ID // (section 4.1.6) if name == "" { ifname = "random" randomBits(nodeID[:]) return true } return false } // NodeID returns a slice of a copy of the current Node ID, setting the Node ID // if not already set. func NodeID() []byte { defer nodeMu.Unlock() nodeMu.Lock() if nodeID == zeroID { setNodeInterface("") } nid := nodeID return nid[:] } // SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes // of id are used. If id is less than 6 bytes then false is returned and the // Node ID is not set. func SetNodeID(id []byte) bool { if len(id) < 6 { return false } defer nodeMu.Unlock() nodeMu.Lock() copy(nodeID[:], id) ifname = "user" return true } // NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is // not valid. The NodeID is only well defined for version 1 and 2 UUIDs. func (uuid UUID) NodeID() []byte { var node [6]byte copy(node[:], uuid[10:]) return node[:] } uuid-1.3.0/node_js.go000066400000000000000000000007631407314152000144340ustar00rootroot00000000000000// Copyright 2017 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. // +build js package uuid // getHardwareInterface returns nil values for the JS version of the code. // This remvoves the "net" dependency, because it is not used in the browser. // Using the "net" library inflates the size of the transpiled JS code by 673k bytes. func getHardwareInterface(name string) (string, []byte) { return "", nil } uuid-1.3.0/node_net.go000066400000000000000000000016651407314152000146100ustar00rootroot00000000000000// Copyright 2017 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. // +build !js package uuid import "net" var interfaces []net.Interface // cached list of interfaces // getHardwareInterface returns the name and hardware address of interface name. // If name is "" then the name and hardware address of one of the system's // interfaces is returned. If no interfaces are found (name does not exist or // there are no interfaces) then "", nil is returned. // // Only addresses of at least 6 bytes are returned. func getHardwareInterface(name string) (string, []byte) { if interfaces == nil { var err error interfaces, err = net.Interfaces() if err != nil { return "", nil } } for _, ifs := range interfaces { if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { return ifs.Name, ifs.HardwareAddr } } return "", nil } uuid-1.3.0/null.go000066400000000000000000000046351407314152000137670ustar00rootroot00000000000000// Copyright 2021 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 uuid import ( "bytes" "database/sql/driver" "encoding/json" "fmt" ) var jsonNull = []byte("null") // NullUUID represents a UUID that may be null. // NullUUID implements the SQL driver.Scanner interface so // it can be used as a scan destination: // // var u uuid.NullUUID // err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) // ... // if u.Valid { // // use u.UUID // } else { // // NULL value // } // type NullUUID struct { UUID UUID Valid bool // Valid is true if UUID is not NULL } // Scan implements the SQL driver.Scanner interface. func (nu *NullUUID) Scan(value interface{}) error { if value == nil { nu.UUID, nu.Valid = Nil, false return nil } err := nu.UUID.Scan(value) if err != nil { nu.Valid = false return err } nu.Valid = true return nil } // Value implements the driver Valuer interface. func (nu NullUUID) Value() (driver.Value, error) { if !nu.Valid { return nil, nil } // Delegate to UUID Value function return nu.UUID.Value() } // MarshalBinary implements encoding.BinaryMarshaler. func (nu NullUUID) MarshalBinary() ([]byte, error) { if nu.Valid { return nu.UUID[:], nil } return []byte(nil), nil } // UnmarshalBinary implements encoding.BinaryUnmarshaler. func (nu *NullUUID) UnmarshalBinary(data []byte) error { if len(data) != 16 { return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) } copy(nu.UUID[:], data) nu.Valid = true return nil } // MarshalText implements encoding.TextMarshaler. func (nu NullUUID) MarshalText() ([]byte, error) { if nu.Valid { return nu.UUID.MarshalText() } return jsonNull, nil } // UnmarshalText implements encoding.TextUnmarshaler. func (nu *NullUUID) UnmarshalText(data []byte) error { id, err := ParseBytes(data) if err != nil { nu.Valid = false return err } nu.UUID = id nu.Valid = true return nil } // MarshalJSON implements json.Marshaler. func (nu NullUUID) MarshalJSON() ([]byte, error) { if nu.Valid { return json.Marshal(nu.UUID) } return jsonNull, nil } // UnmarshalJSON implements json.Unmarshaler. func (nu *NullUUID) UnmarshalJSON(data []byte) error { if bytes.Equal(data, jsonNull) { *nu = NullUUID{} return nil // valid null UUID } err := json.Unmarshal(data, &nu.UUID) nu.Valid = err == nil return err } uuid-1.3.0/null_test.go000066400000000000000000000116611407314152000150230ustar00rootroot00000000000000// Copyright 2021 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 uuid import ( "bytes" "encoding/json" "testing" ) func TestNullUUIDScan(t *testing.T) { var u UUID var nu NullUUID uNilErr := u.Scan(nil) nuNilErr := nu.Scan(nil) if uNilErr != nil && nuNilErr != nil && uNilErr.Error() != nuNilErr.Error() { t.Errorf("expected errors to be equal, got %s, %s", uNilErr, nuNilErr) } uInvalidStringErr := u.Scan("test") nuInvalidStringErr := nu.Scan("test") if uInvalidStringErr != nil && nuInvalidStringErr != nil && uInvalidStringErr.Error() != nuInvalidStringErr.Error() { t.Errorf("expected errors to be equal, got %s, %s", uInvalidStringErr, nuInvalidStringErr) } valid := "12345678-abcd-1234-abcd-0123456789ab" uValidErr := u.Scan(valid) nuValidErr := nu.Scan(valid) if uValidErr != nuValidErr { t.Errorf("expected errors to be equal, got %s, %s", uValidErr, nuValidErr) } } func TestNullUUIDValue(t *testing.T) { var u UUID var nu NullUUID nuValue, nuErr := nu.Value() if nuErr != nil { t.Errorf("expected nil err, got err %s", nuErr) } if nuValue != nil { t.Errorf("expected nil value, got non-nil %s", nuValue) } u = MustParse("12345678-abcd-1234-abcd-0123456789ab") nu = NullUUID{ UUID: MustParse("12345678-abcd-1234-abcd-0123456789ab"), Valid: true, } uValue, uErr := u.Value() nuValue, nuErr = nu.Value() if uErr != nil { t.Errorf("expected nil err, got err %s", uErr) } if nuErr != nil { t.Errorf("expected nil err, got err %s", nuErr) } if uValue != nuValue { t.Errorf("expected uuid %s and nulluuid %s to be equal ", uValue, nuValue) } } func TestNullUUIDMarshalText(t *testing.T) { tests := []struct { nullUUID NullUUID }{ { nullUUID: NullUUID{}, }, { nullUUID: NullUUID{ UUID: MustParse("12345678-abcd-1234-abcd-0123456789ab"), Valid: true, }, }, } for _, test := range tests { var uText []byte var uErr error nuText, nuErr := test.nullUUID.MarshalText() if test.nullUUID.Valid { uText, uErr = test.nullUUID.UUID.MarshalText() } else { uText = []byte("null") } if nuErr != uErr { t.Errorf("expected error %e, got %e", nuErr, uErr) } if !bytes.Equal(nuText, uText) { t.Errorf("expected text data %s, got %s", string(nuText), string(uText)) } } } func TestNullUUIDUnmarshalText(t *testing.T) { tests := []struct { nullUUID NullUUID }{ { nullUUID: NullUUID{}, }, { nullUUID: NullUUID{ UUID: MustParse("12345678-abcd-1234-abcd-0123456789ab"), Valid: true, }, }, } for _, test := range tests { var uText []byte var uErr error nuText, nuErr := test.nullUUID.MarshalText() if test.nullUUID.Valid { uText, uErr = test.nullUUID.UUID.MarshalText() } else { uText = []byte("null") } if nuErr != uErr { t.Errorf("expected error %e, got %e", nuErr, uErr) } if !bytes.Equal(nuText, uText) { t.Errorf("expected text data %s, got %s", string(nuText), string(uText)) } } } func TestNullUUIDMarshalBinary(t *testing.T) { tests := []struct { nullUUID NullUUID }{ { nullUUID: NullUUID{}, }, { nullUUID: NullUUID{ UUID: MustParse("12345678-abcd-1234-abcd-0123456789ab"), Valid: true, }, }, } for _, test := range tests { var uBinary []byte var uErr error nuBinary, nuErr := test.nullUUID.MarshalBinary() if test.nullUUID.Valid { uBinary, uErr = test.nullUUID.UUID.MarshalBinary() } else { uBinary = []byte(nil) } if nuErr != uErr { t.Errorf("expected error %e, got %e", nuErr, uErr) } if !bytes.Equal(nuBinary, uBinary) { t.Errorf("expected binary data %s, got %s", string(nuBinary), string(uBinary)) } } } func TestNullUUIDMarshalJSON(t *testing.T) { jsonNull, _ := json.Marshal(nil) jsonUUID, _ := json.Marshal(MustParse("12345678-abcd-1234-abcd-0123456789ab")) tests := []struct { nullUUID NullUUID expected []byte expectedErr error }{ { nullUUID: NullUUID{}, expected: jsonNull, expectedErr: nil, }, { nullUUID: NullUUID{ UUID: MustParse(string(jsonUUID)), Valid: true, }, expected: []byte(`"12345678-abcd-1234-abcd-0123456789ab"`), expectedErr: nil, }, } for _, test := range tests { data, err := json.Marshal(&test.nullUUID) if err != test.expectedErr { t.Errorf("expected error %e, got %e", test.expectedErr, err) } if !bytes.Equal(data, test.expected) { t.Errorf("expected json data %s, got %s", string(test.expected), string(data)) } } } func TestNullUUIDUnmarshalJSON(t *testing.T) { jsonNull, _ := json.Marshal(nil) jsonUUID, _ := json.Marshal(MustParse("12345678-abcd-1234-abcd-0123456789ab")) var nu NullUUID err := json.Unmarshal(jsonNull, &nu) if err != nil || nu.Valid { t.Errorf("expected nil when unmarshaling null, got %s", err) } err = json.Unmarshal(jsonUUID, &nu) if err != nil || !nu.Valid { t.Errorf("expected nil when unmarshaling null, got %s", err) } } uuid-1.3.0/seq_test.go000066400000000000000000000026431407314152000146410ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "flag" "runtime" "testing" "time" ) // This test is only run when --regressions is passed on the go test line. var regressions = flag.Bool("regressions", false, "run uuid regression tests") // TestClockSeqRace tests for a particular race condition of returning two // identical Version1 UUIDs. The duration of 1 minute was chosen as the race // condition, before being fixed, nearly always occurred in under 30 seconds. func TestClockSeqRace(t *testing.T) { if !*regressions { t.Skip("skipping regression tests") } duration := time.Minute done := make(chan struct{}) defer close(done) ch := make(chan UUID, 10000) ncpu := runtime.NumCPU() switch ncpu { case 0, 1: // We can't run the test effectively. t.Skip("skipping race test, only one CPU detected") return default: runtime.GOMAXPROCS(ncpu) } for i := 0; i < ncpu; i++ { go func() { for { select { case <-done: return case ch <- Must(NewUUID()): } } }() } uuids := make(map[string]bool) cnt := 0 start := time.Now() for u := range ch { s := u.String() if uuids[s] { t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s) return } uuids[s] = true if time.Since(start) > duration { return } cnt++ } } uuid-1.3.0/sql.go000066400000000000000000000026631407314152000136130ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "database/sql/driver" "fmt" ) // Scan implements sql.Scanner so UUIDs can be read from databases transparently. // Currently, database types that map to string and []byte are supported. Please // consult database-specific driver documentation for matching types. func (uuid *UUID) Scan(src interface{}) error { switch src := src.(type) { case nil: return nil case string: // if an empty UUID comes from a table, we return a null UUID if src == "" { return nil } // see Parse for required string format u, err := Parse(src) if err != nil { return fmt.Errorf("Scan: %v", err) } *uuid = u case []byte: // if an empty UUID comes from a table, we return a null UUID if len(src) == 0 { return nil } // assumes a simple slice of bytes if 16 bytes // otherwise attempts to parse if len(src) != 16 { return uuid.Scan(string(src)) } copy((*uuid)[:], src) default: return fmt.Errorf("Scan: unable to scan type %T into UUID", src) } return nil } // Value implements sql.Valuer so that UUIDs can be written to databases // transparently. Currently, UUIDs map to strings. Please consult // database-specific driver documentation for matching types. func (uuid UUID) Value() (driver.Value, error) { return uuid.String(), nil } uuid-1.3.0/sql_test.go000066400000000000000000000045101407314152000146430ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "strings" "testing" ) func TestScan(t *testing.T) { stringTest := "f47ac10b-58cc-0372-8567-0e02b2c3d479" badTypeTest := 6 invalidTest := "f47ac10b-58cc-0372-8567-0e02b2c3d4" byteTest := make([]byte, 16) byteTestUUID := Must(Parse(stringTest)) copy(byteTest, byteTestUUID[:]) // sunny day tests var uuid UUID err := (&uuid).Scan(stringTest) if err != nil { t.Fatal(err) } err = (&uuid).Scan([]byte(stringTest)) if err != nil { t.Fatal(err) } err = (&uuid).Scan(byteTest) if err != nil { t.Fatal(err) } // bad type tests err = (&uuid).Scan(badTypeTest) if err == nil { t.Error("int correctly parsed and shouldn't have") } if !strings.Contains(err.Error(), "unable to scan type") { t.Error("attempting to parse an int returned an incorrect error message") } // invalid/incomplete uuids err = (&uuid).Scan(invalidTest) if err == nil { t.Error("invalid uuid was parsed without error") } if !strings.Contains(err.Error(), "invalid UUID") { t.Error("attempting to parse an invalid UUID returned an incorrect error message") } err = (&uuid).Scan(byteTest[:len(byteTest)-2]) if err == nil { t.Error("invalid byte uuid was parsed without error") } if !strings.Contains(err.Error(), "invalid UUID") { t.Error("attempting to parse an invalid byte UUID returned an incorrect error message") } // empty tests uuid = UUID{} var emptySlice []byte err = (&uuid).Scan(emptySlice) if err != nil { t.Fatal(err) } for _, v := range uuid { if v != 0 { t.Error("UUID was not nil after scanning empty byte slice") } } uuid = UUID{} var emptyString string err = (&uuid).Scan(emptyString) if err != nil { t.Fatal(err) } for _, v := range uuid { if v != 0 { t.Error("UUID was not nil after scanning empty byte slice") } } uuid = UUID{} err = (&uuid).Scan(nil) if err != nil { t.Fatal(err) } for _, v := range uuid { if v != 0 { t.Error("UUID was not nil after scanning nil") } } } func TestValue(t *testing.T) { stringTest := "f47ac10b-58cc-0372-8567-0e02b2c3d479" uuid := Must(Parse(stringTest)) val, _ := uuid.Value() if val != stringTest { t.Error("Value() did not return expected string") } } uuid-1.3.0/time.go000066400000000000000000000066651407314152000137600ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "encoding/binary" "sync" "time" ) // A Time represents a time as the number of 100's of nanoseconds since 15 Oct // 1582. type Time int64 const ( lillian = 2299160 // Julian day of 15 Oct 1582 unix = 2440587 // Julian day of 1 Jan 1970 epoch = unix - lillian // Days between epochs g1582 = epoch * 86400 // seconds between epochs g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs ) var ( timeMu sync.Mutex lasttime uint64 // last time we returned clockSeq uint16 // clock sequence for this run timeNow = time.Now // for testing ) // UnixTime converts t the number of seconds and nanoseconds using the Unix // epoch of 1 Jan 1970. func (t Time) UnixTime() (sec, nsec int64) { sec = int64(t - g1582ns100) nsec = (sec % 10000000) * 100 sec /= 10000000 return sec, nsec } // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and // clock sequence as well as adjusting the clock sequence as needed. An error // is returned if the current time cannot be determined. func GetTime() (Time, uint16, error) { defer timeMu.Unlock() timeMu.Lock() return getTime() } func getTime() (Time, uint16, error) { t := timeNow() // If we don't have a clock sequence already, set one. if clockSeq == 0 { setClockSequence(-1) } now := uint64(t.UnixNano()/100) + g1582ns100 // If time has gone backwards with this clock sequence then we // increment the clock sequence if now <= lasttime { clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 } lasttime = now return Time(now), clockSeq, nil } // ClockSequence returns the current clock sequence, generating one if not // already set. The clock sequence is only used for Version 1 UUIDs. // // The uuid package does not use global static storage for the clock sequence or // the last time a UUID was generated. Unless SetClockSequence is used, a new // random clock sequence is generated the first time a clock sequence is // requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) func ClockSequence() int { defer timeMu.Unlock() timeMu.Lock() return clockSequence() } func clockSequence() int { if clockSeq == 0 { setClockSequence(-1) } return int(clockSeq & 0x3fff) } // SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to // -1 causes a new sequence to be generated. func SetClockSequence(seq int) { defer timeMu.Unlock() timeMu.Lock() setClockSequence(seq) } func setClockSequence(seq int) { if seq == -1 { var b [2]byte randomBits(b[:]) // clock sequence seq = int(b[0])<<8 | int(b[1]) } oldSeq := clockSeq clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant if oldSeq != clockSeq { lasttime = 0 } } // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in // uuid. The time is only defined for version 1 and 2 UUIDs. func (uuid UUID) Time() Time { time := int64(binary.BigEndian.Uint32(uuid[0:4])) time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 return Time(time) } // ClockSequence returns the clock sequence encoded in uuid. // The clock sequence is only well defined for version 1 and 2 UUIDs. func (uuid UUID) ClockSequence() int { return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff } uuid-1.3.0/util.go000066400000000000000000000036001407314152000137610ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "io" ) // randomBits completely fills slice b with random data. func randomBits(b []byte) { if _, err := io.ReadFull(rander, b); err != nil { panic(err.Error()) // rand should never fail } } // xvalues returns the value of a byte as a hexadecimal digit or 255. var xvalues = [256]byte{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, } // xtob converts hex characters x1 and x2 into a byte. func xtob(x1, x2 byte) (byte, bool) { b1 := xvalues[x1] b2 := xvalues[x2] return (b1 << 4) | b2, b1 != 255 && b2 != 255 } uuid-1.3.0/uuid.go000066400000000000000000000170401407314152000137550ustar00rootroot00000000000000// 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 uuid import ( "bytes" "crypto/rand" "encoding/hex" "errors" "fmt" "io" "strings" "sync" ) // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC // 4122. type UUID [16]byte // A Version represents a UUID's version. type Version byte // A Variant represents a UUID's variant. type Variant byte // Constants returned by Variant. const ( Invalid = Variant(iota) // Invalid UUID RFC4122 // The variant specified in RFC4122 Reserved // Reserved, NCS backward compatibility. Microsoft // Reserved, Microsoft Corporation backward compatibility. Future // Reserved for future definition. ) const randPoolSize = 16 * 16 var ( 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 (err invalidLengthError) Error() string { return fmt.Sprintf("invalid UUID length: %d", err.len) } // IsInvalidLengthError is matcher function for custom error invalidLengthError func IsInvalidLengthError(err error) bool { _, ok := err.(invalidLengthError) return ok } // Parse decodes s into a UUID or returns an error. Both the standard UUID // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the // Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex // encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. func Parse(s string) (UUID, error) { var uuid UUID switch len(s) { // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: if strings.ToLower(s[:9]) != "urn:uuid:" { return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) } s = s[9:] // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} case 36 + 2: s = s[1:] // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx case 32: var ok bool for i := range uuid { uuid[i], ok = xtob(s[i*2], s[i*2+1]) if !ok { return uuid, errors.New("invalid UUID format") } } return uuid, nil default: return uuid, invalidLengthError{len(s)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { return uuid, errors.New("invalid UUID format") } for i, x := range [16]int{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { v, ok := xtob(s[x], s[x+1]) if !ok { return uuid, errors.New("invalid UUID format") } uuid[i] = v } return uuid, nil } // ParseBytes is like Parse, except it parses a byte slice instead of a string. func ParseBytes(b []byte) (UUID, error) { var uuid UUID switch len(b) { case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) } b = b[9:] case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} b = b[1:] case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx var ok bool for i := 0; i < 32; i += 2 { uuid[i/2], ok = xtob(b[i], b[i+1]) if !ok { return uuid, errors.New("invalid UUID format") } } return uuid, nil default: return uuid, invalidLengthError{len(b)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { return uuid, errors.New("invalid UUID format") } for i, x := range [16]int{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { v, ok := xtob(b[x], b[x+1]) if !ok { return uuid, errors.New("invalid UUID format") } uuid[i] = v } return uuid, nil } // MustParse is like Parse but panics if the string cannot be parsed. // It simplifies safe initialization of global variables holding compiled UUIDs. func MustParse(s string) UUID { uuid, err := Parse(s) if err != nil { panic(`uuid: Parse(` + s + `): ` + err.Error()) } return uuid } // 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 FromBytes(b []byte) (uuid UUID, err error) { err = uuid.UnmarshalBinary(b) return uuid, err } // Must returns uuid if err is nil and panics otherwise. func Must(uuid UUID, err error) UUID { if err != nil { panic(err) } return uuid } // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // , or "" if uuid is invalid. func (uuid UUID) String() string { var buf [36]byte encodeHex(buf[:], uuid) return string(buf[:]) } // URN returns the RFC 2141 URN form of uuid, // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. func (uuid UUID) URN() string { var buf [36 + 9]byte copy(buf[:], "urn:uuid:") encodeHex(buf[9:], uuid) return string(buf[:]) } func encodeHex(dst []byte, uuid UUID) { hex.Encode(dst, uuid[:4]) dst[8] = '-' hex.Encode(dst[9:13], uuid[4:6]) dst[13] = '-' hex.Encode(dst[14:18], uuid[6:8]) dst[18] = '-' hex.Encode(dst[19:23], uuid[8:10]) dst[23] = '-' hex.Encode(dst[24:], uuid[10:]) } // Variant returns the variant encoded in uuid. func (uuid UUID) Variant() Variant { switch { case (uuid[8] & 0xc0) == 0x80: return RFC4122 case (uuid[8] & 0xe0) == 0xc0: return Microsoft case (uuid[8] & 0xe0) == 0xe0: return Future default: return Reserved } } // Version returns the version of uuid. func (uuid UUID) Version() Version { return Version(uuid[6] >> 4) } func (v Version) String() string { if v > 15 { return fmt.Sprintf("BAD_VERSION_%d", v) } return fmt.Sprintf("VERSION_%d", v) } func (v Variant) String() string { switch v { case RFC4122: return "RFC4122" case Reserved: return "Reserved" case Microsoft: return "Microsoft" case Future: return "Future" case Invalid: return "Invalid" } return fmt.Sprintf("BadVariant%d", int(v)) } // 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 SetRand(r io.Reader) { if r == nil { rander = rand.Reader return } rander = r } // 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 EnableRandPool() { 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 DisableRandPool() { poolEnabled = false defer poolMu.Unlock() poolMu.Lock() poolPos = randPoolSize } uuid-1.3.0/uuid_test.go000066400000000000000000000424031407314152000150150ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "bytes" "fmt" "os" "runtime" "strings" "testing" "time" "unsafe" ) type test struct { in string version Version variant Variant isuuid bool } var tests = []test{ {"f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, RFC4122, true}, {"f47ac10b-58cc-1372-8567-0e02b2c3d479", 1, RFC4122, true}, {"f47ac10b-58cc-2372-8567-0e02b2c3d479", 2, RFC4122, true}, {"f47ac10b-58cc-3372-8567-0e02b2c3d479", 3, RFC4122, true}, {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true}, {"f47ac10b-58cc-5372-8567-0e02b2c3d479", 5, RFC4122, true}, {"f47ac10b-58cc-6372-8567-0e02b2c3d479", 6, RFC4122, true}, {"f47ac10b-58cc-7372-8567-0e02b2c3d479", 7, RFC4122, true}, {"f47ac10b-58cc-8372-8567-0e02b2c3d479", 8, RFC4122, true}, {"f47ac10b-58cc-9372-8567-0e02b2c3d479", 9, RFC4122, true}, {"f47ac10b-58cc-a372-8567-0e02b2c3d479", 10, RFC4122, true}, {"f47ac10b-58cc-b372-8567-0e02b2c3d479", 11, RFC4122, true}, {"f47ac10b-58cc-c372-8567-0e02b2c3d479", 12, RFC4122, true}, {"f47ac10b-58cc-d372-8567-0e02b2c3d479", 13, RFC4122, true}, {"f47ac10b-58cc-e372-8567-0e02b2c3d479", 14, RFC4122, true}, {"f47ac10b-58cc-f372-8567-0e02b2c3d479", 15, RFC4122, true}, {"urn:uuid:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, {"URN:UUID:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-1567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-2567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-3567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-4567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-5567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-6567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-7567-0e02b2c3d479", 4, Reserved, true}, {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true}, {"f47ac10b-58cc-4372-9567-0e02b2c3d479", 4, RFC4122, true}, {"f47ac10b-58cc-4372-a567-0e02b2c3d479", 4, RFC4122, true}, {"f47ac10b-58cc-4372-b567-0e02b2c3d479", 4, RFC4122, true}, {"f47ac10b-58cc-4372-c567-0e02b2c3d479", 4, Microsoft, true}, {"f47ac10b-58cc-4372-d567-0e02b2c3d479", 4, Microsoft, true}, {"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true}, {"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true}, {"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false}, {"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false}, {"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false}, {"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false}, {"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false}, {"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false}, {"{f47ac10b-58cc-0372-8567-0e02b2c3d479}", 0, RFC4122, true}, {"{f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, Invalid, false}, {"f47ac10b-58cc-0372-8567-0e02b2c3d479}", 0, Invalid, false}, {"f47ac10b58cc037285670e02b2c3d479", 0, RFC4122, true}, {"f47ac10b58cc037285670e02b2c3d4790", 0, Invalid, false}, {"f47ac10b58cc037285670e02b2c3d47", 0, Invalid, false}, } var constants = []struct { c interface{} name string }{ {Person, "Person"}, {Group, "Group"}, {Org, "Org"}, {Invalid, "Invalid"}, {RFC4122, "RFC4122"}, {Reserved, "Reserved"}, {Microsoft, "Microsoft"}, {Future, "Future"}, {Domain(17), "Domain17"}, {Variant(42), "BadVariant42"}, } func testTest(t *testing.T, in string, tt test) { uuid, err := Parse(in) if ok := (err == nil); ok != tt.isuuid { t.Errorf("Parse(%s) got %v expected %v\b", in, ok, tt.isuuid) } if err != nil { return } if v := uuid.Variant(); v != tt.variant { t.Errorf("Variant(%s) got %d expected %d\b", in, v, tt.variant) } if v := uuid.Version(); v != tt.version { t.Errorf("Version(%s) got %d expected %d\b", in, v, tt.version) } } func testBytes(t *testing.T, in []byte, tt test) { uuid, err := ParseBytes(in) if ok := (err == nil); ok != tt.isuuid { t.Errorf("ParseBytes(%s) got %v expected %v\b", in, ok, tt.isuuid) } if err != nil { return } suuid, _ := Parse(string(in)) if uuid != suuid { t.Errorf("ParseBytes(%s) got %v expected %v\b", in, uuid, suuid) } } func TestUUID(t *testing.T) { for _, tt := range tests { testTest(t, tt.in, tt) testTest(t, strings.ToUpper(tt.in), tt) testBytes(t, []byte(tt.in), tt) } } func TestFromBytes(t *testing.T) { b := []byte{ 0x7d, 0x44, 0x48, 0x40, 0x9d, 0xc0, 0x11, 0xd1, 0xb2, 0x45, 0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2, } uuid, err := FromBytes(b) if err != nil { t.Fatalf("%s", err) } for i := 0; i < len(uuid); i++ { if b[i] != uuid[i] { t.Fatalf("FromBytes() got %v expected %v\b", uuid[:], b) } } } func TestConstants(t *testing.T) { for x, tt := range constants { v, ok := tt.c.(fmt.Stringer) if !ok { t.Errorf("%x: %v: not a stringer", x, v) } else if s := v.String(); s != tt.name { v, _ := tt.c.(int) t.Errorf("%x: Constant %T:%d gives %q, expected %q", x, tt.c, v, s, tt.name) } } } func TestRandomUUID(t *testing.T) { m := make(map[string]bool) for x := 1; x < 32; x++ { uuid := New() s := uuid.String() if m[s] { t.Errorf("NewRandom returned duplicated UUID %s", s) } m[s] = true if v := uuid.Version(); v != 4 { t.Errorf("Random UUID of version %s", v) } if uuid.Variant() != RFC4122 { t.Errorf("Random UUID is variant %d", uuid.Variant()) } } } func TestRandomUUID_Pooled(t *testing.T) { defer DisableRandPool() EnableRandPool() m := make(map[string]bool) for x := 1; x < 128; x++ { uuid := New() s := uuid.String() if m[s] { t.Errorf("NewRandom returned duplicated UUID %s", s) } m[s] = true if v := uuid.Version(); v != 4 { t.Errorf("Random UUID of version %s", v) } if uuid.Variant() != RFC4122 { t.Errorf("Random UUID is variant %d", uuid.Variant()) } } } func TestNew(t *testing.T) { m := make(map[UUID]bool) for x := 1; x < 32; x++ { s := New() if m[s] { t.Errorf("New returned duplicated UUID %s", s) } m[s] = true uuid, err := Parse(s.String()) if err != nil { t.Errorf("New.String() returned %q which does not decode", s) continue } if v := uuid.Version(); v != 4 { t.Errorf("Random UUID of version %s", v) } if uuid.Variant() != RFC4122 { t.Errorf("Random UUID is variant %d", uuid.Variant()) } } } func TestClockSeq(t *testing.T) { // Fake time.Now for this test to return a monotonically advancing time; restore it at end. defer func(orig func() time.Time) { timeNow = orig }(timeNow) monTime := time.Now() timeNow = func() time.Time { monTime = monTime.Add(1 * time.Second) return monTime } SetClockSequence(-1) uuid1, err := NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } uuid2, err := NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } if s1, s2 := uuid1.ClockSequence(), uuid2.ClockSequence(); s1 != s2 { t.Errorf("clock sequence %d != %d", s1, s2) } SetClockSequence(-1) uuid2, err = NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } // Just on the very off chance we generated the same sequence // two times we try again. if uuid1.ClockSequence() == uuid2.ClockSequence() { SetClockSequence(-1) uuid2, err = NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } } if s1, s2 := uuid1.ClockSequence(), uuid2.ClockSequence(); s1 == s2 { t.Errorf("Duplicate clock sequence %d", s1) } SetClockSequence(0x1234) uuid1, err = NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } if seq := uuid1.ClockSequence(); seq != 0x1234 { t.Errorf("%s: expected seq 0x1234 got 0x%04x", uuid1, seq) } } func TestCoding(t *testing.T) { text := "7d444840-9dc0-11d1-b245-5ffdce74fad2" urn := "urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2" data := UUID{ 0x7d, 0x44, 0x48, 0x40, 0x9d, 0xc0, 0x11, 0xd1, 0xb2, 0x45, 0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2, } if v := data.String(); v != text { t.Errorf("%x: encoded to %s, expected %s", data, v, text) } if v := data.URN(); v != urn { t.Errorf("%x: urn is %s, expected %s", data, v, urn) } uuid, err := Parse(text) if err != nil { t.Errorf("Parse returned unexpected error %v", err) } if data != uuid { t.Errorf("%s: decoded to %s, expected %s", text, uuid, data) } } func TestVersion1(t *testing.T) { uuid1, err := NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } uuid2, err := NewUUID() if err != nil { t.Fatalf("could not create UUID: %v", err) } if uuid1 == uuid2 { t.Errorf("%s:duplicate uuid", uuid1) } if v := uuid1.Version(); v != 1 { t.Errorf("%s: version %s expected 1", uuid1, v) } if v := uuid2.Version(); v != 1 { t.Errorf("%s: version %s expected 1", uuid2, v) } n1 := uuid1.NodeID() n2 := uuid2.NodeID() if !bytes.Equal(n1, n2) { t.Errorf("Different nodes %x != %x", n1, n2) } t1 := uuid1.Time() t2 := uuid2.Time() q1 := uuid1.ClockSequence() q2 := uuid2.ClockSequence() switch { case t1 == t2 && q1 == q2: t.Error("time stopped") case t1 > t2 && q1 == q2: t.Error("time reversed") case t1 < t2 && q1 != q2: t.Error("clock sequence changed unexpectedly") } } func TestNode(t *testing.T) { // This test is mostly to make sure we don't leave nodeMu locked. ifname = "" if ni := NodeInterface(); ni != "" { t.Errorf("NodeInterface got %q, want %q", ni, "") } if SetNodeInterface("xyzzy") { t.Error("SetNodeInterface succeeded on a bad interface name") } if !SetNodeInterface("") { t.Error("SetNodeInterface failed") } if runtime.GOARCH != "js" { if ni := NodeInterface(); ni == "" { t.Error("NodeInterface returned an empty string") } } ni := NodeID() if len(ni) != 6 { t.Errorf("ni got %d bytes, want 6", len(ni)) } hasData := false for _, b := range ni { if b != 0 { hasData = true } } if !hasData { t.Error("nodeid is all zeros") } id := []byte{1, 2, 3, 4, 5, 6, 7, 8} SetNodeID(id) ni = NodeID() if !bytes.Equal(ni, id[:6]) { t.Errorf("got nodeid %v, want %v", ni, id[:6]) } if ni := NodeInterface(); ni != "user" { t.Errorf("got interface %q, want %q", ni, "user") } } func TestNodeAndTime(t *testing.T) { // Time is February 5, 1998 12:30:23.136364800 AM GMT uuid, err := Parse("7d444840-9dc0-11d1-b245-5ffdce74fad2") if err != nil { t.Fatalf("Parser returned unexpected error %v", err) } node := []byte{0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2} ts := uuid.Time() c := time.Unix(ts.UnixTime()) want := time.Date(1998, 2, 5, 0, 30, 23, 136364800, time.UTC) if !c.Equal(want) { t.Errorf("Got time %v, want %v", c, want) } if !bytes.Equal(node, uuid.NodeID()) { t.Errorf("Expected node %v got %v", node, uuid.NodeID()) } } func TestMD5(t *testing.T) { uuid := NewMD5(NameSpaceDNS, []byte("python.org")).String() want := "6fa459ea-ee8a-3ca4-894e-db77e160355e" if uuid != want { t.Errorf("MD5: got %q expected %q", uuid, want) } } func TestSHA1(t *testing.T) { uuid := NewSHA1(NameSpaceDNS, []byte("python.org")).String() want := "886313e1-3b8a-5372-9b90-0c9aee199e5d" if uuid != want { t.Errorf("SHA1: got %q expected %q", uuid, want) } } func TestNodeID(t *testing.T) { nid := []byte{1, 2, 3, 4, 5, 6} SetNodeInterface("") s := NodeInterface() if runtime.GOARCH != "js" { if s == "" || s == "user" { t.Errorf("NodeInterface %q after SetInterface", s) } } node1 := NodeID() if node1 == nil { t.Error("NodeID nil after SetNodeInterface", s) } SetNodeID(nid) s = NodeInterface() if s != "user" { t.Errorf("Expected NodeInterface %q got %q", "user", s) } node2 := NodeID() if node2 == nil { t.Error("NodeID nil after SetNodeID", s) } if bytes.Equal(node1, node2) { t.Error("NodeID not changed after SetNodeID", s) } else if !bytes.Equal(nid, node2) { t.Errorf("NodeID is %x, expected %x", node2, nid) } } func testDCE(t *testing.T, name string, uuid UUID, err error, domain Domain, id uint32) { if err != nil { t.Errorf("%s failed: %v", name, err) return } if v := uuid.Version(); v != 2 { t.Errorf("%s: %s: expected version 2, got %s", name, uuid, v) return } if v := uuid.Domain(); v != domain { t.Errorf("%s: %s: expected domain %d, got %d", name, uuid, domain, v) } if v := uuid.ID(); v != id { t.Errorf("%s: %s: expected id %d, got %d", name, uuid, id, v) } } func TestDCE(t *testing.T) { uuid, err := NewDCESecurity(42, 12345678) testDCE(t, "NewDCESecurity", uuid, err, 42, 12345678) uuid, err = NewDCEPerson() testDCE(t, "NewDCEPerson", uuid, err, Person, uint32(os.Getuid())) uuid, err = NewDCEGroup() testDCE(t, "NewDCEGroup", uuid, err, Group, uint32(os.Getgid())) } type badRand struct{} func (r badRand) Read(buf []byte) (int, error) { for i := range buf { buf[i] = byte(i) } return len(buf), nil } func TestBadRand(t *testing.T) { SetRand(badRand{}) uuid1 := New() uuid2 := New() if uuid1 != uuid2 { t.Errorf("expected duplicates, got %q and %q", uuid1, uuid2) } SetRand(nil) uuid1 = New() uuid2 = New() if uuid1 == uuid2 { t.Errorf("unexpected duplicates, got %q", uuid1) } } func TestSetRand(t *testing.T) { myString := "805-9dd6-1a877cb526c678e71d38-7122-44c0-9b7c-04e7001cc78783ac3e82-47a3-4cc3-9951-13f3339d88088f5d685a-11f7-4078-ada9-de44ad2daeb7" SetRand(strings.NewReader(myString)) uuid1 := New() uuid2 := New() SetRand(strings.NewReader(myString)) uuid3 := New() uuid4 := New() if uuid1 != uuid3 { t.Errorf("expected duplicates, got %q and %q", uuid1, uuid3) } if uuid2 != uuid4 { t.Errorf("expected duplicates, got %q and %q", uuid2, uuid4) } } func TestRandomFromReader(t *testing.T) { myString := "8059ddhdle77cb52" r := bytes.NewReader([]byte(myString)) r2 := bytes.NewReader([]byte(myString)) uuid1, err := NewRandomFromReader(r) if err != nil { t.Errorf("failed generating UUID from a reader") } _, err = NewRandomFromReader(r) if err == nil { t.Errorf("expecting an error as reader has no more bytes. Got uuid. NewRandomFromReader may not be using the provided reader") } uuid3, err := NewRandomFromReader(r2) if err != nil { t.Errorf("failed generating UUID from a reader") } if uuid1 != uuid3 { t.Errorf("expected duplicates, got %q and %q", uuid1, uuid3) } } func TestRandPool(t *testing.T) { myString := "8059ddhdle77cb52" EnableRandPool() SetRand(strings.NewReader(myString)) _, err := NewRandom() if err == nil { t.Errorf("expecting an error as reader has no more bytes") } DisableRandPool() SetRand(strings.NewReader(myString)) _, err = NewRandom() if err != nil { t.Errorf("failed generating UUID from a reader") } } func TestWrongLength(t *testing.T) { _, err := Parse("12345") if err == nil { t.Errorf("expected ‘12345’ was invalid") } else if err.Error() != "invalid UUID length: 5" { t.Errorf("expected a different error message for an invalid length") } } func TestIsWrongLength(t *testing.T) { _, err := Parse("12345") if !IsInvalidLengthError(err) { t.Errorf("expected error type is invalidLengthError") } } var asString = "f47ac10b-58cc-0372-8567-0e02b2c3d479" var asBytes = []byte(asString) func BenchmarkParse(b *testing.B) { for i := 0; i < b.N; i++ { _, err := Parse(asString) if err != nil { b.Fatal(err) } } } func BenchmarkParseBytes(b *testing.B) { for i := 0; i < b.N; i++ { _, err := ParseBytes(asBytes) if err != nil { b.Fatal(err) } } } // parseBytesUnsafe is to benchmark using unsafe. func parseBytesUnsafe(b []byte) (UUID, error) { return Parse(*(*string)(unsafe.Pointer(&b))) } func BenchmarkParseBytesUnsafe(b *testing.B) { for i := 0; i < b.N; i++ { _, err := parseBytesUnsafe(asBytes) if err != nil { b.Fatal(err) } } } // parseBytesCopy is to benchmark not using unsafe. func parseBytesCopy(b []byte) (UUID, error) { return Parse(string(b)) } func BenchmarkParseBytesCopy(b *testing.B) { for i := 0; i < b.N; i++ { _, err := parseBytesCopy(asBytes) if err != nil { b.Fatal(err) } } } func BenchmarkNew(b *testing.B) { for i := 0; i < b.N; i++ { New() } } func BenchmarkUUID_String(b *testing.B) { uuid, err := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") if err != nil { b.Fatal(err) } for i := 0; i < b.N; i++ { if uuid.String() == "" { b.Fatal("invalid uuid") } } } func BenchmarkUUID_URN(b *testing.B) { uuid, err := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") if err != nil { b.Fatal(err) } for i := 0; i < b.N; i++ { if uuid.URN() == "" { b.Fatal("invalid uuid") } } } func BenchmarkParseBadLength(b *testing.B) { short := asString[:10] for i := 0; i < b.N; i++ { _, err := Parse(short) if err == nil { b.Fatalf("expected ‘%s’ was invalid", short) } } } func BenchmarkParseLen32Truncated(b *testing.B) { partial := asString[:len(asString)-4] for i := 0; i < b.N; i++ { _, err := Parse(partial) if err == nil { b.Fatalf("expected ‘%s’ was invalid", partial) } } } func BenchmarkParseLen36Corrupted(b *testing.B) { wrong := asString[:len(asString)-1] + "x" for i := 0; i < b.N; i++ { _, err := Parse(wrong) if err == nil { b.Fatalf("expected ‘%s’ was invalid", wrong) } } } func BenchmarkUUID_New(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { _, err := NewRandom() if err != nil { b.Fatal(err) } } }) } func BenchmarkUUID_NewPooled(b *testing.B) { EnableRandPool() b.RunParallel(func(pb *testing.PB) { for pb.Next() { _, err := NewRandom() if err != nil { b.Fatal(err) } } }) } uuid-1.3.0/version1.go000066400000000000000000000023511407314152000145540ustar00rootroot00000000000000// Copyright 2016 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 uuid import ( "encoding/binary" ) // NewUUID returns a Version 1 UUID based on the current NodeID and clock // sequence, and the current time. If the NodeID has not been set by SetNodeID // or SetNodeInterface then it will be set automatically. If the NodeID cannot // be set NewUUID returns nil. If clock sequence has not been set by // SetClockSequence then it will be set automatically. If GetTime fails to // return the current NewUUID returns nil and an error. // // In most cases, New should be used. func NewUUID() (UUID, error) { var uuid UUID now, seq, err := GetTime() if err != nil { return uuid, err } timeLow := uint32(now & 0xffffffff) timeMid := uint16((now >> 32) & 0xffff) timeHi := uint16((now >> 48) & 0x0fff) timeHi |= 0x1000 // Version 1 binary.BigEndian.PutUint32(uuid[0:], timeLow) binary.BigEndian.PutUint16(uuid[4:], timeMid) binary.BigEndian.PutUint16(uuid[6:], timeHi) binary.BigEndian.PutUint16(uuid[8:], seq) nodeMu.Lock() if nodeID == zeroID { setNodeInterface("") } copy(uuid[10:], nodeID[:]) nodeMu.Unlock() return uuid, nil } uuid-1.3.0/version4.go000066400000000000000000000040111407314152000145520ustar00rootroot00000000000000// Copyright 2016 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 uuid import "io" // New creates a new random UUID or panics. New is equivalent to // the expression // // uuid.Must(uuid.NewRandom()) func New() UUID { return Must(NewRandom()) } // NewString creates a new random UUID and returns it as a string or panics. // NewString is equivalent to the expression // // uuid.New().String() func NewString() string { return Must(NewRandom()).String() } // NewRandom returns a Random (Version 4) UUID. // // The strength of the UUIDs is based on the strength of the crypto/rand // package. // // Uses the randomness pool if it was enabled with EnableRandPool. // // A note about uniqueness derived from the UUID Wikipedia entry: // // Randomly generated UUIDs have 122 random bits. One's annual risk of being // hit by a meteorite is estimated to be one chance in 17 billion, that // means the probability is about 0.00000000006 (6 × 10−11), // equivalent to the odds of creating a few tens of trillions of UUIDs in a // year and having one duplicate. func NewRandom() (UUID, error) { if !poolEnabled { return NewRandomFromReader(rander) } return newRandomFromPool() } // NewRandomFromReader returns a UUID based on bytes read from a given io.Reader. func NewRandomFromReader(r io.Reader) (UUID, error) { var uuid UUID _, err := io.ReadFull(r, uuid[:]) if err != nil { return Nil, err } uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 return uuid, nil } func newRandomFromPool() (UUID, error) { var uuid UUID poolMu.Lock() if poolPos == randPoolSize { _, err := io.ReadFull(rander, pool[:]) if err != nil { poolMu.Unlock() return Nil, err } poolPos = 0 } copy(uuid[:], pool[poolPos:(poolPos+16)]) poolPos += 16 poolMu.Unlock() uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 return uuid, nil }