Skip to content

Commit

Permalink
Change a UUID from []byte to [16]byte along with other API changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
bormanp committed Feb 19, 2016
1 parent 82d3e37 commit 9e951e1
Show file tree
Hide file tree
Showing 18 changed files with 395 additions and 353 deletions.
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# 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.
8 changes: 8 additions & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
Paul Borman <borman@google.com>
bmatsuo
shawnps
theory
jboverfelt
dsymonds
cd1
wallclockbuilder
dansouza
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ This project was automatically exported from code.google.com/p/go-uuid
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
The uuid package generates and inspects UUIDs based on [RFC 412](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`

Expand Down
34 changes: 15 additions & 19 deletions dce.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2011 Google Inc. All rights reserved.
// 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.

Expand Down Expand Up @@ -29,46 +29,42 @@ const (
//
// 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 {
uuid := NewUUID()
if uuid != nil {
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
return uuid, err
}

// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
// domain with the id returned by os.Getuid.
//
// NewDCEPerson(Person, uint32(os.Getuid()))
func NewDCEPerson() UUID {
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.
//
// NewDCEGroup(Group, uint32(os.Getgid()))
func NewDCEGroup() UUID {
func NewDCEGroup() (UUID, error) {
return NewDCESecurity(Group, uint32(os.Getgid()))
}

// Domain returns the domain for a Version 2 UUID or false.
func (uuid UUID) Domain() (Domain, bool) {
if v, _ := uuid.Version(); v != 2 {
return 0, false
}
return Domain(uuid[9]), true
// 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 or false.
func (uuid UUID) Id() (uint32, bool) {
if v, _ := uuid.Version(); v != 2 {
return 0, false
}
return binary.BigEndian.Uint32(uuid[0:4]), true
// Id returns the id for a Version 2 UUID. Ids are only defined for Vrsion 2
// UUIDs.
func (uuid UUID) Id() uint32 {
return binary.BigEndian.Uint32(uuid[0:4])
}

func (d Domain) String() string {
Expand Down
10 changes: 7 additions & 3 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// Copyright 2011 Google Inc. All rights reserved.
// 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.

// The uuid package generates and inspects UUIDs.
// Package uuid generates and inspects UUIDs.
//
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
// 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
24 changes: 12 additions & 12 deletions hash.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2011 Google Inc. All rights reserved.
// 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.

Expand All @@ -10,13 +10,13 @@ import (
"hash"
)

// Well known Name Space IDs and UUIDs
// Well known namespace IDs and UUIDs
var (
NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
NIL = Parse("00000000-0000-0000-0000-000000000000")
NameSpace_DNS = MustParse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
NameSpace_URL = MustParse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
NameSpace_OID = MustParse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
NameSpace_X500 = MustParse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
NIL UUID // empty UUID, all zeros
)

// NewHash returns a new UUID derived from the hash of space concatenated with
Expand All @@ -26,26 +26,26 @@ var (
// NewMD5 and NewSHA1.
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
h.Reset()
h.Write(space)
h.Write(space[:])
h.Write([]byte(data))
s := h.Sum(nil)
uuid := make([]byte, 16)
copy(uuid, s)
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.
// 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.
// supplied name space and data. It is the same as calling:
//
// NewHash(sha1.New(), space, data, 5)
func NewSHA1(space UUID, data []byte) UUID {
Expand Down
11 changes: 6 additions & 5 deletions json_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2014 Google Inc. All rights reserved.
// 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.

Expand All @@ -10,7 +10,7 @@ import (
"testing"
)

var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
var testUUID = MustParse("f47ac10b-58cc-0372-8567-0e02b2c3d479")

func TestJSON(t *testing.T) {
type S struct {
Expand All @@ -35,9 +35,10 @@ func BenchmarkUUID_MarshalJSON(b *testing.B) {
x := &struct {
UUID UUID `json:"uuid"`
}{}
x.UUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
if x.UUID == nil {
b.Fatal("invalid 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)
Expand Down
42 changes: 42 additions & 0 deletions marshal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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"
"unsafe"
)

// MarshalText implements encoding.TextMarshaler.
func (u UUID) MarshalText() ([]byte, error) {
var js [36]byte
encodeHex(js[:], u)
return js[:], nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (u *UUID) UnmarshalText(data []byte) error {
// See comment in ParseBytes why we do this.
// id, err := ParseBytes(data)
id, err := Parse(*(*string)(unsafe.Pointer(&data)))
if err == nil {
*u = id
}
return err
}

// MarshalBinary implements encoding.BinaryMarshaler.
func (u UUID) MarshalBinary() ([]byte, error) {
return u[:], nil
}

// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (u *UUID) UnmarshalBinary(data []byte) error {
if len(data) != 16 {
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
}
copy(u[:], data)
return nil
}
48 changes: 17 additions & 31 deletions node.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2011 Google Inc. All rights reserved.
// 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.

Expand All @@ -13,7 +13,8 @@ var (
nodeMu sync.Mutex
interfaces []net.Interface // cached list of interfaces
ifname string // name of interface being used
nodeID []byte // hardware for version 1 UUIDs
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
Expand Down Expand Up @@ -48,21 +49,17 @@ func setNodeInterface(name string) bool {

for _, ifs := range interfaces {
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
if setNodeID(ifs.HardwareAddr) {
ifname = ifs.Name
return true
}
copy(nodeID[:], ifs.HardwareAddr)
ifname = ifs.Name
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 == "" {
if nodeID == nil {
nodeID = make([]byte, 6)
}
randomBits(nodeID)
randomBits(nodeID[:])
return true
}
return false
Expand All @@ -73,35 +70,24 @@ func setNodeInterface(name string) bool {
func NodeID() []byte {
defer nodeMu.Unlock()
nodeMu.Lock()
if nodeID == nil {
if nodeID == zeroID {
setNodeInterface("")
}
nid := make([]byte, 6)
copy(nid, nodeID)
return nid
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 {
defer nodeMu.Unlock()
nodeMu.Lock()
if setNodeID(id) {
ifname = "user"
return true
}
return false
}

func setNodeID(id []byte) bool {
if len(id) < 6 {
return false
}
if nodeID == nil {
nodeID = make([]byte, 6)
}
copy(nodeID, id)
defer nodeMu.Unlock()
nodeMu.Lock()
copy(nodeID[:], id)
ifname = "user"
return true
}

Expand All @@ -111,7 +97,7 @@ func (uuid UUID) NodeID() []byte {
if len(uuid) != 16 {
return nil
}
node := make([]byte, 6)
copy(node, uuid[10:])
return node
var node [6]byte
copy(node[:], uuid[10:])
return node[:]
}
4 changes: 2 additions & 2 deletions seq_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2014 Google Inc. All rights reserved.
// 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.

Expand Down Expand Up @@ -42,7 +42,7 @@ func TestClockSeqRace(t *testing.T) {
select {
case <-done:
return
case ch <- NewUUID():
case ch <- MustNewUUID():
}
}
}()
Expand Down

0 comments on commit 9e951e1

Please sign in to comment.