完善依赖

This commit is contained in:
eson 2019-01-06 05:48:59 +08:00
parent f827851cf4
commit 086b040c52
6 changed files with 136 additions and 97 deletions

6
Gopkg.lock generated
View File

@ -85,12 +85,12 @@
version = "v1.4.1"
[[projects]]
digest = "1:274f67cb6fed9588ea2521ecdac05a6d62a8c51c074c1fccc6a49a40ba80e925"
branch = "master"
digest = "1:a3b8912deeef29007fab9a13a9f21b9e9b59c621a2ed61e2fe7b37320a71fbd5"
name = "github.com/satori/go.uuid"
packages = ["."]
pruneopts = "UT"
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
version = "v1.2.0"
revision = "b2ce2384e17bbe0c6d34077efa39dbab3e09123b"
[[projects]]
digest = "1:2cab41f59638fdb77dda96ab4f9b5860ef30f48967557254eba127e43c756f2e"

View File

@ -50,6 +50,10 @@
name = "github.com/tidwall/gjson"
version = "1.1.3"
[[override]]
name = "github.com/satori/go.uuid"
branch = "master"
[prune]
go-tests = true
unused-packages = true

1
article/vendor Symbolic link
View File

@ -0,0 +1 @@
../vendor

View File

@ -1,14 +1,12 @@
language: go
sudo: false
go:
- 1.2
- 1.3
- 1.4
- 1.5
- 1.6
- 1.7
- 1.8
- 1.9
- 1.6.x
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
- tip
matrix:
allow_failures:

View File

@ -1,8 +1,8 @@
# UUID package for Go language
[![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid)
[![Build Status](https://travis-ci.org/satori/go.uuid.svg?branch=master)](https://travis-ci.org/satori/go.uuid)
[![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid)
[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid)
[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.svg)](http://godoc.org/github.com/satori/go.uuid)
This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs.
@ -23,7 +23,7 @@ Use the `go` command:
## Requirements
UUID package requires Go >= 1.2.
UUID package tested against Go >= 1.6.
## Example
@ -37,13 +37,23 @@ import (
func main() {
// Creating UUID Version 4
u1 := uuid.NewV4()
// panic on error
u1 := uuid.Must(uuid.NewV4())
fmt.Printf("UUIDv4: %s\n", u1)
// or error handling
u2, err := uuid.NewV4()
if err != nil {
fmt.Printf("Something went wrong: %s", err)
return
}
fmt.Printf("UUIDv4: %s\n", u2)
// Parsing UUID from string input
u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
fmt.Printf("Something gone wrong: %s", err)
fmt.Printf("Something went wrong: %s", err)
return
}
fmt.Printf("Successfully parsed: %s", u2)
}

View File

@ -26,7 +26,9 @@ import (
"crypto/rand"
"crypto/sha1"
"encoding/binary"
"fmt"
"hash"
"io"
"net"
"os"
"sync"
@ -37,21 +39,23 @@ import (
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000
var (
global = newDefaultGenerator()
type epochFunc func() time.Time
type hwAddrFunc func() (net.HardwareAddr, error)
epochFunc = unixTimeFunc
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
var (
global = newRFC4122Generator()
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)
// NewV1 returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
func NewV1() (UUID, error) {
return global.NewV1()
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
func NewV2(domain byte) (UUID, error) {
return global.NewV2(domain)
}
@ -61,7 +65,7 @@ func NewV3(ns UUID, name string) UUID {
}
// NewV4 returns random generated UUID.
func NewV4() UUID {
func NewV4() (UUID, error) {
return global.NewV4()
}
@ -72,74 +76,85 @@ func NewV5(ns UUID, name string) UUID {
// Generator provides interface for generating UUIDs.
type Generator interface {
NewV1() UUID
NewV2(domain byte) UUID
NewV1() (UUID, error)
NewV2(domain byte) (UUID, error)
NewV3(ns UUID, name string) UUID
NewV4() UUID
NewV4() (UUID, error)
NewV5(ns UUID, name string) UUID
}
// Default generator implementation.
type generator struct {
storageOnce sync.Once
storageMutex sync.Mutex
type rfc4122Generator struct {
clockSequenceOnce sync.Once
hardwareAddrOnce sync.Once
storageMutex sync.Mutex
rand io.Reader
epochFunc epochFunc
hwAddrFunc hwAddrFunc
lastTime uint64
clockSequence uint16
hardwareAddr [6]byte
}
func newDefaultGenerator() Generator {
return &generator{}
func newRFC4122Generator() Generator {
return &rfc4122Generator{
epochFunc: time.Now,
hwAddrFunc: defaultHWAddrFunc,
rand: rand.Reader,
}
}
// NewV1 returns UUID based on current timestamp and MAC address.
func (g *generator) NewV1() UUID {
func (g *rfc4122Generator) NewV1() (UUID, error) {
u := UUID{}
timeNow, clockSeq, hardwareAddr := g.getStorage()
timeNow, clockSeq, err := g.getClockSequence()
if err != nil {
return Nil, err
}
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
hardwareAddr, err := g.getHardwareAddr()
if err != nil {
return Nil, err
}
copy(u[10:], hardwareAddr)
u.SetVersion(V1)
u.SetVariant(VariantRFC4122)
return u
return u, nil
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func (g *generator) NewV2(domain byte) UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := g.getStorage()
func (g *rfc4122Generator) NewV2(domain byte) (UUID, error) {
u, err := g.NewV1()
if err != nil {
return Nil, err
}
switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[0:], posixUID)
binary.BigEndian.PutUint32(u[:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[0:], posixGID)
binary.BigEndian.PutUint32(u[:], posixGID)
}
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
u[9] = domain
copy(u[10:], hardwareAddr)
u.SetVersion(V2)
u.SetVariant(VariantRFC4122)
return u
return u, nil
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func (g *generator) NewV3(ns UUID, name string) UUID {
func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
u.SetVersion(V3)
u.SetVariant(VariantRFC4122)
@ -148,17 +163,19 @@ func (g *generator) NewV3(ns UUID, name string) UUID {
}
// NewV4 returns random generated UUID.
func (g *generator) NewV4() UUID {
func (g *rfc4122Generator) NewV4() (UUID, error) {
u := UUID{}
g.safeRandom(u[:])
if _, err := io.ReadFull(g.rand, u[:]); err != nil {
return Nil, err
}
u.SetVersion(V4)
u.SetVariant(VariantRFC4122)
return u
return u, nil
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func (g *generator) NewV5(ns UUID, name string) UUID {
func (g *rfc4122Generator) NewV5(ns UUID, name string) UUID {
u := newFromHash(sha1.New(), ns, name)
u.SetVersion(V5)
u.SetVariant(VariantRFC4122)
@ -166,66 +183,61 @@ func (g *generator) NewV5(ns UUID, name string) UUID {
return u
}
func (g *generator) initStorage() {
g.initClockSequence()
g.initHardwareAddr()
}
func (g *generator) initClockSequence() {
buf := make([]byte, 2)
g.safeRandom(buf)
g.clockSequence = binary.BigEndian.Uint16(buf)
}
func (g *generator) initHardwareAddr() {
interfaces, err := net.Interfaces()
if err == nil {
for _, iface := range interfaces {
if len(iface.HardwareAddr) >= 6 {
copy(g.hardwareAddr[:], iface.HardwareAddr)
return
}
// Returns epoch and clock sequence.
func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) {
var err error
g.clockSequenceOnce.Do(func() {
buf := make([]byte, 2)
if _, err = io.ReadFull(g.rand, buf); err != nil {
return
}
g.clockSequence = binary.BigEndian.Uint16(buf)
})
if err != nil {
return 0, 0, err
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence
g.safeRandom(g.hardwareAddr[:])
// Set multicast bit as recommended in RFC 4122
g.hardwareAddr[0] |= 0x01
}
func (g *generator) safeRandom(dest []byte) {
if _, err := rand.Read(dest); err != nil {
panic(err)
}
}
// Returns UUID v1/v2 storage state.
// Returns epoch timestamp, clock sequence, and hardware address.
func (g *generator) getStorage() (uint64, uint16, []byte) {
g.storageOnce.Do(g.initStorage)
g.storageMutex.Lock()
defer g.storageMutex.Unlock()
timeNow := epochFunc()
// Clock changed backwards since last UUID generation.
timeNow := g.getEpoch()
// Clock didn't change since last UUID generation.
// Should increase clock sequence.
if timeNow <= g.lastTime {
g.clockSequence++
}
g.lastTime = timeNow
return timeNow, g.clockSequence, g.hardwareAddr[:]
return timeNow, g.clockSequence, nil
}
// Returns hardware address.
func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) {
var err error
g.hardwareAddrOnce.Do(func() {
if hwAddr, err := g.hwAddrFunc(); err == nil {
copy(g.hardwareAddr[:], hwAddr)
return
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence.
if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil {
return
}
// Set multicast bit as recommended by RFC 4122
g.hardwareAddr[0] |= 0x01
})
if err != nil {
return []byte{}, err
}
return g.hardwareAddr[:], nil
}
// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
return epochStart + uint64(time.Now().UnixNano()/100)
func (g *rfc4122Generator) getEpoch() uint64 {
return epochStart + uint64(g.epochFunc().UnixNano()/100)
}
// Returns UUID based on hashing of namespace UUID and name.
@ -237,3 +249,17 @@ func newFromHash(h hash.Hash, ns UUID, name string) UUID {
return u
}
// Returns hardware address.
func defaultHWAddrFunc() (net.HardwareAddr, error) {
ifaces, err := net.Interfaces()
if err != nil {
return []byte{}, err
}
for _, iface := range ifaces {
if len(iface.HardwareAddr) >= 6 {
return iface.HardwareAddr, nil
}
}
return []byte{}, fmt.Errorf("uuid: no HW address found")
}