mirror of
https://github.com/adnanh/webhook.git
synced 2025-06-26 22:38:31 +00:00
Update gofrs/uuid dependency to v5
This commit is contained in:
parent
1d00387284
commit
81a17df5e0
16 changed files with 857 additions and 606 deletions
2
go.mod
2
go.mod
|
@ -8,7 +8,7 @@ require (
|
|||
github.com/fsnotify/fsnotify v1.4.7 // indirect
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-chi/chi/v5 v5.0.12
|
||||
github.com/gofrs/uuid v3.2.0+incompatible
|
||||
github.com/gofrs/uuid/v5 v5.0.0
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8
|
||||
|
|
4
go.sum
4
go.sum
|
@ -8,8 +8,8 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
|||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/gofrs/uuid/v5"
|
||||
)
|
||||
|
||||
// Key to use when setting the request ID.
|
||||
|
|
23
vendor/github.com/gofrs/uuid/.travis.yml
generated
vendored
23
vendor/github.com/gofrs/uuid/.travis.yml
generated
vendored
|
@ -1,23 +0,0 @@
|
|||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
fast_finish: true
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
script:
|
||||
- go test ./... -race -coverprofile=coverage.txt -covermode=atomic
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
notifications:
|
||||
email: false
|
212
vendor/github.com/gofrs/uuid/codec.go
generated
vendored
212
vendor/github.com/gofrs/uuid/codec.go
generated
vendored
|
@ -1,212 +0,0 @@
|
|||
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FromBytes returns a UUID generated from the raw byte slice input.
|
||||
// It will return an error if the slice isn't 16 bytes long.
|
||||
func FromBytes(input []byte) (UUID, error) {
|
||||
u := UUID{}
|
||||
err := u.UnmarshalBinary(input)
|
||||
return u, err
|
||||
}
|
||||
|
||||
// FromBytesOrNil returns a UUID generated from the raw byte slice input.
|
||||
// Same behavior as FromBytes(), but returns uuid.Nil instead of an error.
|
||||
func FromBytesOrNil(input []byte) UUID {
|
||||
uuid, err := FromBytes(input)
|
||||
if err != nil {
|
||||
return Nil
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// FromString returns a UUID parsed from the input string.
|
||||
// Input is expected in a form accepted by UnmarshalText.
|
||||
func FromString(input string) (UUID, error) {
|
||||
u := UUID{}
|
||||
err := u.UnmarshalText([]byte(input))
|
||||
return u, err
|
||||
}
|
||||
|
||||
// FromStringOrNil returns a UUID parsed from the input string.
|
||||
// Same behavior as FromString(), but returns uuid.Nil instead of an error.
|
||||
func FromStringOrNil(input string) UUID {
|
||||
uuid, err := FromString(input)
|
||||
if err != nil {
|
||||
return Nil
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
// The encoding is the same as returned by the String() method.
|
||||
func (u UUID) MarshalText() ([]byte, error) {
|
||||
return []byte(u.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// Following formats are supported:
|
||||
//
|
||||
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
||||
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
|
||||
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
// "6ba7b8109dad11d180b400c04fd430c8"
|
||||
// "{6ba7b8109dad11d180b400c04fd430c8}",
|
||||
// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8"
|
||||
//
|
||||
// ABNF for supported UUID text representation follows:
|
||||
//
|
||||
// URN := 'urn'
|
||||
// UUID-NID := 'uuid'
|
||||
//
|
||||
// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
|
||||
// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
|
||||
// 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
|
||||
//
|
||||
// hexoct := hexdig hexdig
|
||||
// 2hexoct := hexoct hexoct
|
||||
// 4hexoct := 2hexoct 2hexoct
|
||||
// 6hexoct := 4hexoct 2hexoct
|
||||
// 12hexoct := 6hexoct 6hexoct
|
||||
//
|
||||
// hashlike := 12hexoct
|
||||
// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
|
||||
//
|
||||
// plain := canonical | hashlike
|
||||
// uuid := canonical | hashlike | braced | urn
|
||||
//
|
||||
// braced := '{' plain '}' | '{' hashlike '}'
|
||||
// urn := URN ':' UUID-NID ':' plain
|
||||
//
|
||||
func (u *UUID) UnmarshalText(text []byte) error {
|
||||
switch len(text) {
|
||||
case 32:
|
||||
return u.decodeHashLike(text)
|
||||
case 34, 38:
|
||||
return u.decodeBraced(text)
|
||||
case 36:
|
||||
return u.decodeCanonical(text)
|
||||
case 41, 45:
|
||||
return u.decodeURN(text)
|
||||
default:
|
||||
return fmt.Errorf("uuid: incorrect UUID length: %s", text)
|
||||
}
|
||||
}
|
||||
|
||||
// decodeCanonical decodes UUID strings that are formatted as defined in RFC-4122 (section 3):
|
||||
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8".
|
||||
func (u *UUID) decodeCanonical(t []byte) error {
|
||||
if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' {
|
||||
return fmt.Errorf("uuid: incorrect UUID format %s", t)
|
||||
}
|
||||
|
||||
src := t
|
||||
dst := u[:]
|
||||
|
||||
for i, byteGroup := range byteGroups {
|
||||
if i > 0 {
|
||||
src = src[1:] // skip dash
|
||||
}
|
||||
_, err := hex.Decode(dst[:byteGroup/2], src[:byteGroup])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
src = src[byteGroup:]
|
||||
dst = dst[byteGroup/2:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeHashLike decodes UUID strings that are using the following format:
|
||||
// "6ba7b8109dad11d180b400c04fd430c8".
|
||||
func (u *UUID) decodeHashLike(t []byte) error {
|
||||
src := t[:]
|
||||
dst := u[:]
|
||||
|
||||
_, err := hex.Decode(dst, src)
|
||||
return err
|
||||
}
|
||||
|
||||
// decodeBraced decodes UUID strings that are using the following formats:
|
||||
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
|
||||
// "{6ba7b8109dad11d180b400c04fd430c8}".
|
||||
func (u *UUID) decodeBraced(t []byte) error {
|
||||
l := len(t)
|
||||
|
||||
if t[0] != '{' || t[l-1] != '}' {
|
||||
return fmt.Errorf("uuid: incorrect UUID format %s", t)
|
||||
}
|
||||
|
||||
return u.decodePlain(t[1 : l-1])
|
||||
}
|
||||
|
||||
// decodeURN decodes UUID strings that are using the following formats:
|
||||
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8".
|
||||
func (u *UUID) decodeURN(t []byte) error {
|
||||
total := len(t)
|
||||
|
||||
urnUUIDPrefix := t[:9]
|
||||
|
||||
if !bytes.Equal(urnUUIDPrefix, urnPrefix) {
|
||||
return fmt.Errorf("uuid: incorrect UUID format: %s", t)
|
||||
}
|
||||
|
||||
return u.decodePlain(t[9:total])
|
||||
}
|
||||
|
||||
// decodePlain decodes UUID strings that are using the following formats:
|
||||
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format
|
||||
// "6ba7b8109dad11d180b400c04fd430c8".
|
||||
func (u *UUID) decodePlain(t []byte) error {
|
||||
switch len(t) {
|
||||
case 32:
|
||||
return u.decodeHashLike(t)
|
||||
case 36:
|
||||
return u.decodeCanonical(t)
|
||||
default:
|
||||
return fmt.Errorf("uuid: incorrect UUID length: %s", t)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
||||
func (u UUID) MarshalBinary() ([]byte, error) {
|
||||
return u.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
||||
// It will return an error if the slice isn't 16 bytes long.
|
||||
func (u *UUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != Size {
|
||||
return fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
|
||||
}
|
||||
copy(u[:], data)
|
||||
|
||||
return nil
|
||||
}
|
299
vendor/github.com/gofrs/uuid/generator.go
generated
vendored
299
vendor/github.com/gofrs/uuid/generator.go
generated
vendored
|
@ -1,299 +0,0 @@
|
|||
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Difference in 100-nanosecond intervals between
|
||||
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
|
||||
const epochStart = 122192928000000000
|
||||
|
||||
type epochFunc func() time.Time
|
||||
|
||||
// HWAddrFunc is the function type used to provide hardware (MAC) addresses.
|
||||
type HWAddrFunc func() (net.HardwareAddr, error)
|
||||
|
||||
// DefaultGenerator is the default UUID Generator used by this package.
|
||||
var DefaultGenerator Generator = NewGen()
|
||||
|
||||
var (
|
||||
posixUID = uint32(os.Getuid())
|
||||
posixGID = uint32(os.Getgid())
|
||||
)
|
||||
|
||||
// NewV1 returns a UUID based on the current timestamp and MAC address.
|
||||
func NewV1() (UUID, error) {
|
||||
return DefaultGenerator.NewV1()
|
||||
}
|
||||
|
||||
// NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
|
||||
func NewV2(domain byte) (UUID, error) {
|
||||
return DefaultGenerator.NewV2(domain)
|
||||
}
|
||||
|
||||
// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
|
||||
func NewV3(ns UUID, name string) UUID {
|
||||
return DefaultGenerator.NewV3(ns, name)
|
||||
}
|
||||
|
||||
// NewV4 returns a randomly generated UUID.
|
||||
func NewV4() (UUID, error) {
|
||||
return DefaultGenerator.NewV4()
|
||||
}
|
||||
|
||||
// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
|
||||
func NewV5(ns UUID, name string) UUID {
|
||||
return DefaultGenerator.NewV5(ns, name)
|
||||
}
|
||||
|
||||
// Generator provides an interface for generating UUIDs.
|
||||
type Generator interface {
|
||||
NewV1() (UUID, error)
|
||||
NewV2(domain byte) (UUID, error)
|
||||
NewV3(ns UUID, name string) UUID
|
||||
NewV4() (UUID, error)
|
||||
NewV5(ns UUID, name string) UUID
|
||||
}
|
||||
|
||||
// Gen is a reference UUID generator based on the specifications laid out in
|
||||
// RFC-4122 and DCE 1.1: Authentication and Security Services. This type
|
||||
// satisfies the Generator interface as defined in this package.
|
||||
//
|
||||
// For consumers who are generating V1 UUIDs, but don't want to expose the MAC
|
||||
// address of the node generating the UUIDs, the NewGenWithHWAF() function has been
|
||||
// provided as a convenience. See the function's documentation for more info.
|
||||
//
|
||||
// The authors of this package do not feel that the majority of users will need
|
||||
// to obfuscate their MAC address, and so we recommend using NewGen() to create
|
||||
// a new generator.
|
||||
type Gen struct {
|
||||
clockSequenceOnce sync.Once
|
||||
hardwareAddrOnce sync.Once
|
||||
storageMutex sync.Mutex
|
||||
|
||||
rand io.Reader
|
||||
|
||||
epochFunc epochFunc
|
||||
hwAddrFunc HWAddrFunc
|
||||
lastTime uint64
|
||||
clockSequence uint16
|
||||
hardwareAddr [6]byte
|
||||
}
|
||||
|
||||
// interface check -- build will fail if *Gen doesn't satisfy Generator
|
||||
var _ Generator = (*Gen)(nil)
|
||||
|
||||
// NewGen returns a new instance of Gen with some default values set. Most
|
||||
// people should use this.
|
||||
func NewGen() *Gen {
|
||||
return NewGenWithHWAF(defaultHWAddrFunc)
|
||||
}
|
||||
|
||||
// NewGenWithHWAF builds a new UUID generator with the HWAddrFunc provided. Most
|
||||
// consumers should use NewGen() instead.
|
||||
//
|
||||
// This is used so that consumers can generate their own MAC addresses, for use
|
||||
// in the generated UUIDs, if there is some concern about exposing the physical
|
||||
// address of the machine generating the UUID.
|
||||
//
|
||||
// The Gen generator will only invoke the HWAddrFunc once, and cache that MAC
|
||||
// address for all the future UUIDs generated by it. If you'd like to switch the
|
||||
// MAC address being used, you'll need to create a new generator using this
|
||||
// function.
|
||||
func NewGenWithHWAF(hwaf HWAddrFunc) *Gen {
|
||||
return &Gen{
|
||||
epochFunc: time.Now,
|
||||
hwAddrFunc: hwaf,
|
||||
rand: rand.Reader,
|
||||
}
|
||||
}
|
||||
|
||||
// NewV1 returns a UUID based on the current timestamp and MAC address.
|
||||
func (g *Gen) NewV1() (UUID, error) {
|
||||
u := UUID{}
|
||||
|
||||
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, nil
|
||||
}
|
||||
|
||||
// NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
|
||||
func (g *Gen) NewV2(domain byte) (UUID, error) {
|
||||
u, err := g.NewV1()
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
switch domain {
|
||||
case DomainPerson:
|
||||
binary.BigEndian.PutUint32(u[:], posixUID)
|
||||
case DomainGroup:
|
||||
binary.BigEndian.PutUint32(u[:], posixGID)
|
||||
}
|
||||
|
||||
u[9] = domain
|
||||
|
||||
u.SetVersion(V2)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
|
||||
func (g *Gen) NewV3(ns UUID, name string) UUID {
|
||||
u := newFromHash(md5.New(), ns, name)
|
||||
u.SetVersion(V3)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// NewV4 returns a randomly generated UUID.
|
||||
func (g *Gen) NewV4() (UUID, error) {
|
||||
u := UUID{}
|
||||
if _, err := io.ReadFull(g.rand, u[:]); err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
u.SetVersion(V4)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
|
||||
func (g *Gen) NewV5(ns UUID, name string) UUID {
|
||||
u := newFromHash(sha1.New(), ns, name)
|
||||
u.SetVersion(V5)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// Returns the epoch and clock sequence.
|
||||
func (g *Gen) 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
|
||||
}
|
||||
|
||||
g.storageMutex.Lock()
|
||||
defer g.storageMutex.Unlock()
|
||||
|
||||
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, nil
|
||||
}
|
||||
|
||||
// Returns the hardware address.
|
||||
func (g *Gen) getHardwareAddr() ([]byte, error) {
|
||||
var err error
|
||||
g.hardwareAddrOnce.Do(func() {
|
||||
var hwAddr net.HardwareAddr
|
||||
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 the difference between UUID epoch (October 15, 1582)
|
||||
// and current time in 100-nanosecond intervals.
|
||||
func (g *Gen) getEpoch() uint64 {
|
||||
return epochStart + uint64(g.epochFunc().UnixNano()/100)
|
||||
}
|
||||
|
||||
// Returns the UUID based on the hashing of the namespace UUID and name.
|
||||
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
||||
u := UUID{}
|
||||
h.Write(ns[:])
|
||||
h.Write([]byte(name))
|
||||
copy(u[:], h.Sum(nil))
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// Returns the 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")
|
||||
}
|
0
vendor/github.com/gofrs/uuid/.gitignore → vendor/github.com/gofrs/uuid/v5/.gitignore
generated
vendored
0
vendor/github.com/gofrs/uuid/.gitignore → vendor/github.com/gofrs/uuid/v5/.gitignore
generated
vendored
0
vendor/github.com/gofrs/uuid/LICENSE → vendor/github.com/gofrs/uuid/v5/LICENSE
generated
vendored
0
vendor/github.com/gofrs/uuid/LICENSE → vendor/github.com/gofrs/uuid/v5/LICENSE
generated
vendored
34
vendor/github.com/gofrs/uuid/README.md → vendor/github.com/gofrs/uuid/v5/README.md
generated
vendored
34
vendor/github.com/gofrs/uuid/README.md → vendor/github.com/gofrs/uuid/v5/README.md
generated
vendored
|
@ -12,11 +12,18 @@ and parsing of UUIDs in different formats.
|
|||
|
||||
This package supports the following UUID versions:
|
||||
* Version 1, based on timestamp and MAC address (RFC-4122)
|
||||
* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
|
||||
* Version 3, based on MD5 hashing of a named value (RFC-4122)
|
||||
* Version 4, based on random numbers (RFC-4122)
|
||||
* Version 5, based on SHA-1 hashing of a named value (RFC-4122)
|
||||
|
||||
This package also supports experimental Universally Unique Identifier implementations based on a
|
||||
[draft RFC](https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html) that updates RFC-4122
|
||||
* Version 6, a k-sortable id based on timestamp, and field-compatible with v1 (draft-peabody-dispatch-new-uuid-format, RFC-4122)
|
||||
* Version 7, a k-sortable id based on timestamp (draft-peabody-dispatch-new-uuid-format, RFC-4122)
|
||||
|
||||
The v6 and v7 IDs are **not** considered a part of the stable API, and may be subject to behavior or API changes as part of minor releases
|
||||
to this package. They will be updated as the draft RFC changes, and will become stable if and when the draft RFC is accepted.
|
||||
|
||||
## Project History
|
||||
|
||||
This project was originally forked from the
|
||||
|
@ -41,31 +48,9 @@ We recommend using v2.0.0+ of this package, as versions prior to 2.0.0 were
|
|||
created before our fork of the original package and have some known
|
||||
deficiencies.
|
||||
|
||||
## Installation
|
||||
|
||||
It is recommended to use a package manager like `dep` that understands tagged
|
||||
releases of a package, as well as semantic versioning.
|
||||
|
||||
If you are unable to make use of a dependency manager with your project, you can
|
||||
use the `go get` command to download it directly:
|
||||
|
||||
```Shell
|
||||
$ go get github.com/gofrs/uuid
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
Due to subtests not being supported in older versions of Go, this package is
|
||||
only regularly tested against Go 1.7+. This package may work perfectly fine with
|
||||
Go 1.2+, but support for these older versions is not actively maintained.
|
||||
|
||||
## Go 1.11 Modules
|
||||
|
||||
As of v3.2.0, this repository no longer adopts Go modules, and v3.2.0 no longer has a `go.mod` file. As a result, v3.2.0 also drops support for the `github.com/gofrs/uuid/v3` import path. Only module-based consumers are impacted. With the v3.2.0 release, _all_ gofrs/uuid consumers should use the `github.com/gofrs/uuid` import path.
|
||||
|
||||
An existing module-based consumer will continue to be able to build using the `github.com/gofrs/uuid/v3` import path using any valid consumer `go.mod` that worked prior to the publishing of v3.2.0, but any module-based consumer should start using the `github.com/gofrs/uuid` import path when possible and _must_ use the `github.com/gofrs/uuid` import path prior to upgrading to v3.2.0.
|
||||
|
||||
Please refer to [Issue #61](https://github.com/gofrs/uuid/issues/61) and [Issue #66](https://github.com/gofrs/uuid/issues/66) for more details.
|
||||
This package requres Go 1.17 or later
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -107,3 +92,4 @@ func main() {
|
|||
|
||||
* [RFC-4122](https://tools.ietf.org/html/rfc4122)
|
||||
* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01)
|
||||
* [New UUID Formats RFC Draft (Peabody) Rev 04](https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html#)
|
234
vendor/github.com/gofrs/uuid/v5/codec.go
generated
vendored
Normal file
234
vendor/github.com/gofrs/uuid/v5/codec.go
generated
vendored
Normal file
|
@ -0,0 +1,234 @@
|
|||
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FromBytes returns a UUID generated from the raw byte slice input.
|
||||
// It will return an error if the slice isn't 16 bytes long.
|
||||
func FromBytes(input []byte) (UUID, error) {
|
||||
u := UUID{}
|
||||
err := u.UnmarshalBinary(input)
|
||||
return u, err
|
||||
}
|
||||
|
||||
// FromBytesOrNil returns a UUID generated from the raw byte slice input.
|
||||
// Same behavior as FromBytes(), but returns uuid.Nil instead of an error.
|
||||
func FromBytesOrNil(input []byte) UUID {
|
||||
uuid, err := FromBytes(input)
|
||||
if err != nil {
|
||||
return Nil
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
var errInvalidFormat = errors.New("uuid: invalid UUID format")
|
||||
|
||||
func fromHexChar(c byte) byte {
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
return c - '0'
|
||||
case 'a' <= c && c <= 'f':
|
||||
return c - 'a' + 10
|
||||
case 'A' <= c && c <= 'F':
|
||||
return c - 'A' + 10
|
||||
}
|
||||
return 255
|
||||
}
|
||||
|
||||
// Parse parses the UUID stored in the string text. Parsing and supported
|
||||
// formats are the same as UnmarshalText.
|
||||
func (u *UUID) Parse(s string) error {
|
||||
switch len(s) {
|
||||
case 32: // hash
|
||||
case 36: // canonical
|
||||
case 34, 38:
|
||||
if s[0] != '{' || s[len(s)-1] != '}' {
|
||||
return fmt.Errorf("uuid: incorrect UUID format in string %q", s)
|
||||
}
|
||||
s = s[1 : len(s)-1]
|
||||
case 41, 45:
|
||||
if s[:9] != "urn:uuid:" {
|
||||
return fmt.Errorf("uuid: incorrect UUID format in string %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
default:
|
||||
return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(s), s)
|
||||
}
|
||||
// canonical
|
||||
if len(s) == 36 {
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return fmt.Errorf("uuid: incorrect UUID format in string %q", s)
|
||||
}
|
||||
for i, x := range [16]byte{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
v1 := fromHexChar(s[x])
|
||||
v2 := fromHexChar(s[x+1])
|
||||
if v1|v2 == 255 {
|
||||
return errInvalidFormat
|
||||
}
|
||||
u[i] = (v1 << 4) | v2
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// hash like
|
||||
for i := 0; i < 32; i += 2 {
|
||||
v1 := fromHexChar(s[i])
|
||||
v2 := fromHexChar(s[i+1])
|
||||
if v1|v2 == 255 {
|
||||
return errInvalidFormat
|
||||
}
|
||||
u[i/2] = (v1 << 4) | v2
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromString returns a UUID parsed from the input string.
|
||||
// Input is expected in a form accepted by UnmarshalText.
|
||||
func FromString(text string) (UUID, error) {
|
||||
var u UUID
|
||||
err := u.Parse(text)
|
||||
return u, err
|
||||
}
|
||||
|
||||
// FromStringOrNil returns a UUID parsed from the input string.
|
||||
// Same behavior as FromString(), but returns uuid.Nil instead of an error.
|
||||
func FromStringOrNil(input string) UUID {
|
||||
uuid, err := FromString(input)
|
||||
if err != nil {
|
||||
return Nil
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
// The encoding is the same as returned by the String() method.
|
||||
func (u UUID) MarshalText() ([]byte, error) {
|
||||
var buf [36]byte
|
||||
encodeCanonical(buf[:], u)
|
||||
return buf[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// Following formats are supported:
|
||||
//
|
||||
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
||||
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
|
||||
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
// "6ba7b8109dad11d180b400c04fd430c8"
|
||||
// "{6ba7b8109dad11d180b400c04fd430c8}",
|
||||
// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8"
|
||||
//
|
||||
// ABNF for supported UUID text representation follows:
|
||||
//
|
||||
// URN := 'urn'
|
||||
// UUID-NID := 'uuid'
|
||||
//
|
||||
// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
|
||||
// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
|
||||
// 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
|
||||
//
|
||||
// hexoct := hexdig hexdig
|
||||
// 2hexoct := hexoct hexoct
|
||||
// 4hexoct := 2hexoct 2hexoct
|
||||
// 6hexoct := 4hexoct 2hexoct
|
||||
// 12hexoct := 6hexoct 6hexoct
|
||||
//
|
||||
// hashlike := 12hexoct
|
||||
// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
|
||||
//
|
||||
// plain := canonical | hashlike
|
||||
// uuid := canonical | hashlike | braced | urn
|
||||
//
|
||||
// braced := '{' plain '}' | '{' hashlike '}'
|
||||
// urn := URN ':' UUID-NID ':' plain
|
||||
func (u *UUID) UnmarshalText(b []byte) error {
|
||||
switch len(b) {
|
||||
case 32: // hash
|
||||
case 36: // canonical
|
||||
case 34, 38:
|
||||
if b[0] != '{' || b[len(b)-1] != '}' {
|
||||
return fmt.Errorf("uuid: incorrect UUID format in string %q", b)
|
||||
}
|
||||
b = b[1 : len(b)-1]
|
||||
case 41, 45:
|
||||
if string(b[:9]) != "urn:uuid:" {
|
||||
return fmt.Errorf("uuid: incorrect UUID format in string %q", b[:9])
|
||||
}
|
||||
b = b[9:]
|
||||
default:
|
||||
return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(b), b)
|
||||
}
|
||||
if len(b) == 36 {
|
||||
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
||||
return fmt.Errorf("uuid: incorrect UUID format in string %q", b)
|
||||
}
|
||||
for i, x := range [16]byte{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
v1 := fromHexChar(b[x])
|
||||
v2 := fromHexChar(b[x+1])
|
||||
if v1|v2 == 255 {
|
||||
return errInvalidFormat
|
||||
}
|
||||
u[i] = (v1 << 4) | v2
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for i := 0; i < 32; i += 2 {
|
||||
v1 := fromHexChar(b[i])
|
||||
v2 := fromHexChar(b[i+1])
|
||||
if v1|v2 == 255 {
|
||||
return errInvalidFormat
|
||||
}
|
||||
u[i/2] = (v1 << 4) | v2
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
||||
func (u UUID) MarshalBinary() ([]byte, error) {
|
||||
return u.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
||||
// It will return an error if the slice isn't 16 bytes long.
|
||||
func (u *UUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != Size {
|
||||
return fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
|
||||
}
|
||||
copy(u[:], data)
|
||||
|
||||
return nil
|
||||
}
|
11
vendor/github.com/gofrs/uuid/fuzz.go → vendor/github.com/gofrs/uuid/v5/fuzz.go
generated
vendored
11
vendor/github.com/gofrs/uuid/fuzz.go → vendor/github.com/gofrs/uuid/v5/fuzz.go
generated
vendored
|
@ -19,6 +19,7 @@
|
|||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package uuid
|
||||
|
@ -27,15 +28,15 @@ package uuid
|
|||
//
|
||||
// To run:
|
||||
//
|
||||
// $ go get github.com/dvyukov/go-fuzz/...
|
||||
// $ cd $GOPATH/src/github.com/gofrs/uuid
|
||||
// $ go-fuzz-build github.com/gofrs/uuid
|
||||
// $ go-fuzz -bin=uuid-fuzz.zip -workdir=./testdata
|
||||
// $ go get github.com/dvyukov/go-fuzz/...
|
||||
// $ cd $GOPATH/src/github.com/gofrs/uuid
|
||||
// $ go-fuzz-build github.com/gofrs/uuid
|
||||
// $ go-fuzz -bin=uuid-fuzz.zip -workdir=./testdata
|
||||
//
|
||||
// If you make significant changes to FromString / UnmarshalText and add
|
||||
// new cases to fromStringTests (in codec_test.go), please run
|
||||
//
|
||||
// $ go test -seed_fuzz_corpus
|
||||
// $ go test -seed_fuzz_corpus
|
||||
//
|
||||
// to seed the corpus with the new interesting inputs, then run the fuzzer.
|
||||
func Fuzz(data []byte) int {
|
456
vendor/github.com/gofrs/uuid/v5/generator.go
generated
vendored
Normal file
456
vendor/github.com/gofrs/uuid/v5/generator.go
generated
vendored
Normal file
|
@ -0,0 +1,456 @@
|
|||
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Difference in 100-nanosecond intervals between
|
||||
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
|
||||
const epochStart = 122192928000000000
|
||||
|
||||
// EpochFunc is the function type used to provide the current time.
|
||||
type EpochFunc func() time.Time
|
||||
|
||||
// HWAddrFunc is the function type used to provide hardware (MAC) addresses.
|
||||
type HWAddrFunc func() (net.HardwareAddr, error)
|
||||
|
||||
// DefaultGenerator is the default UUID Generator used by this package.
|
||||
var DefaultGenerator Generator = NewGen()
|
||||
|
||||
// NewV1 returns a UUID based on the current timestamp and MAC address.
|
||||
func NewV1() (UUID, error) {
|
||||
return DefaultGenerator.NewV1()
|
||||
}
|
||||
|
||||
// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
|
||||
func NewV3(ns UUID, name string) UUID {
|
||||
return DefaultGenerator.NewV3(ns, name)
|
||||
}
|
||||
|
||||
// NewV4 returns a randomly generated UUID.
|
||||
func NewV4() (UUID, error) {
|
||||
return DefaultGenerator.NewV4()
|
||||
}
|
||||
|
||||
// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
|
||||
func NewV5(ns UUID, name string) UUID {
|
||||
return DefaultGenerator.NewV5(ns, name)
|
||||
}
|
||||
|
||||
// NewV6 returns a k-sortable UUID based on a timestamp and 48 bits of
|
||||
// pseudorandom data. The timestamp in a V6 UUID is the same as V1, with the bit
|
||||
// order being adjusted to allow the UUID to be k-sortable.
|
||||
//
|
||||
// This is implemented based on revision 03 of the Peabody UUID draft, and may
|
||||
// be subject to change pending further revisions. Until the final specification
|
||||
// revision is finished, changes required to implement updates to the spec will
|
||||
// not be considered a breaking change. They will happen as a minor version
|
||||
// releases until the spec is final.
|
||||
func NewV6() (UUID, error) {
|
||||
return DefaultGenerator.NewV6()
|
||||
}
|
||||
|
||||
// NewV7 returns a k-sortable UUID based on the current millisecond precision
|
||||
// UNIX epoch and 74 bits of pseudorandom data. It supports single-node batch generation (multiple UUIDs in the same timestamp) with a Monotonic Random counter.
|
||||
//
|
||||
// This is implemented based on revision 04 of the Peabody UUID draft, and may
|
||||
// be subject to change pending further revisions. Until the final specification
|
||||
// revision is finished, changes required to implement updates to the spec will
|
||||
// not be considered a breaking change. They will happen as a minor version
|
||||
// releases until the spec is final.
|
||||
func NewV7() (UUID, error) {
|
||||
return DefaultGenerator.NewV7()
|
||||
}
|
||||
|
||||
// Generator provides an interface for generating UUIDs.
|
||||
type Generator interface {
|
||||
NewV1() (UUID, error)
|
||||
NewV3(ns UUID, name string) UUID
|
||||
NewV4() (UUID, error)
|
||||
NewV5(ns UUID, name string) UUID
|
||||
NewV6() (UUID, error)
|
||||
NewV7() (UUID, error)
|
||||
}
|
||||
|
||||
// Gen is a reference UUID generator based on the specifications laid out in
|
||||
// RFC-4122 and DCE 1.1: Authentication and Security Services. This type
|
||||
// satisfies the Generator interface as defined in this package.
|
||||
//
|
||||
// For consumers who are generating V1 UUIDs, but don't want to expose the MAC
|
||||
// address of the node generating the UUIDs, the NewGenWithHWAF() function has been
|
||||
// provided as a convenience. See the function's documentation for more info.
|
||||
//
|
||||
// The authors of this package do not feel that the majority of users will need
|
||||
// to obfuscate their MAC address, and so we recommend using NewGen() to create
|
||||
// a new generator.
|
||||
type Gen struct {
|
||||
clockSequenceOnce sync.Once
|
||||
hardwareAddrOnce sync.Once
|
||||
storageMutex sync.Mutex
|
||||
|
||||
rand io.Reader
|
||||
|
||||
epochFunc EpochFunc
|
||||
hwAddrFunc HWAddrFunc
|
||||
lastTime uint64
|
||||
clockSequence uint16
|
||||
hardwareAddr [6]byte
|
||||
}
|
||||
|
||||
// GenOption is a function type that can be used to configure a Gen generator.
|
||||
type GenOption func(*Gen)
|
||||
|
||||
// interface check -- build will fail if *Gen doesn't satisfy Generator
|
||||
var _ Generator = (*Gen)(nil)
|
||||
|
||||
// NewGen returns a new instance of Gen with some default values set. Most
|
||||
// people should use this.
|
||||
func NewGen() *Gen {
|
||||
return NewGenWithHWAF(defaultHWAddrFunc)
|
||||
}
|
||||
|
||||
// NewGenWithHWAF builds a new UUID generator with the HWAddrFunc provided. Most
|
||||
// consumers should use NewGen() instead.
|
||||
//
|
||||
// This is used so that consumers can generate their own MAC addresses, for use
|
||||
// in the generated UUIDs, if there is some concern about exposing the physical
|
||||
// address of the machine generating the UUID.
|
||||
//
|
||||
// The Gen generator will only invoke the HWAddrFunc once, and cache that MAC
|
||||
// address for all the future UUIDs generated by it. If you'd like to switch the
|
||||
// MAC address being used, you'll need to create a new generator using this
|
||||
// function.
|
||||
func NewGenWithHWAF(hwaf HWAddrFunc) *Gen {
|
||||
return NewGenWithOptions(WithHWAddrFunc(hwaf))
|
||||
}
|
||||
|
||||
// NewGenWithOptions returns a new instance of Gen with the options provided.
|
||||
// Most people should use NewGen() or NewGenWithHWAF() instead.
|
||||
//
|
||||
// To customize the generator, you can pass in one or more GenOption functions.
|
||||
// For example:
|
||||
//
|
||||
// gen := NewGenWithOptions(
|
||||
// WithHWAddrFunc(myHWAddrFunc),
|
||||
// WithEpochFunc(myEpochFunc),
|
||||
// WithRandomReader(myRandomReader),
|
||||
// )
|
||||
//
|
||||
// NewGenWithOptions(WithHWAddrFunc(myHWAddrFunc)) is equivalent to calling
|
||||
// NewGenWithHWAF(myHWAddrFunc)
|
||||
// NewGenWithOptions() is equivalent to calling NewGen()
|
||||
func NewGenWithOptions(opts ...GenOption) *Gen {
|
||||
gen := &Gen{
|
||||
epochFunc: time.Now,
|
||||
hwAddrFunc: defaultHWAddrFunc,
|
||||
rand: rand.Reader,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(gen)
|
||||
}
|
||||
|
||||
return gen
|
||||
}
|
||||
|
||||
// WithHWAddrFunc is a GenOption that allows you to provide your own HWAddrFunc
|
||||
// function.
|
||||
// When this option is nil, the defaultHWAddrFunc is used.
|
||||
func WithHWAddrFunc(hwaf HWAddrFunc) GenOption {
|
||||
return func(gen *Gen) {
|
||||
if hwaf == nil {
|
||||
hwaf = defaultHWAddrFunc
|
||||
}
|
||||
|
||||
gen.hwAddrFunc = hwaf
|
||||
}
|
||||
}
|
||||
|
||||
// WithEpochFunc is a GenOption that allows you to provide your own EpochFunc
|
||||
// function.
|
||||
// When this option is nil, time.Now is used.
|
||||
func WithEpochFunc(epochf EpochFunc) GenOption {
|
||||
return func(gen *Gen) {
|
||||
if epochf == nil {
|
||||
epochf = time.Now
|
||||
}
|
||||
|
||||
gen.epochFunc = epochf
|
||||
}
|
||||
}
|
||||
|
||||
// WithRandomReader is a GenOption that allows you to provide your own random
|
||||
// reader.
|
||||
// When this option is nil, the default rand.Reader is used.
|
||||
func WithRandomReader(reader io.Reader) GenOption {
|
||||
return func(gen *Gen) {
|
||||
if reader == nil {
|
||||
reader = rand.Reader
|
||||
}
|
||||
|
||||
gen.rand = reader
|
||||
}
|
||||
}
|
||||
|
||||
// NewV1 returns a UUID based on the current timestamp and MAC address.
|
||||
func (g *Gen) NewV1() (UUID, error) {
|
||||
u := UUID{}
|
||||
|
||||
timeNow, clockSeq, err := g.getClockSequence(false)
|
||||
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, nil
|
||||
}
|
||||
|
||||
// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
|
||||
func (g *Gen) NewV3(ns UUID, name string) UUID {
|
||||
u := newFromHash(md5.New(), ns, name)
|
||||
u.SetVersion(V3)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// NewV4 returns a randomly generated UUID.
|
||||
func (g *Gen) NewV4() (UUID, error) {
|
||||
u := UUID{}
|
||||
if _, err := io.ReadFull(g.rand, u[:]); err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
u.SetVersion(V4)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
|
||||
func (g *Gen) NewV5(ns UUID, name string) UUID {
|
||||
u := newFromHash(sha1.New(), ns, name)
|
||||
u.SetVersion(V5)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// NewV6 returns a k-sortable UUID based on a timestamp and 48 bits of
|
||||
// pseudorandom data. The timestamp in a V6 UUID is the same as V1, with the bit
|
||||
// order being adjusted to allow the UUID to be k-sortable.
|
||||
//
|
||||
// This is implemented based on revision 03 of the Peabody UUID draft, and may
|
||||
// be subject to change pending further revisions. Until the final specification
|
||||
// revision is finished, changes required to implement updates to the spec will
|
||||
// not be considered a breaking change. They will happen as a minor version
|
||||
// releases until the spec is final.
|
||||
func (g *Gen) NewV6() (UUID, error) {
|
||||
var u UUID
|
||||
|
||||
if _, err := io.ReadFull(g.rand, u[10:]); err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
timeNow, clockSeq, err := g.getClockSequence(false)
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
binary.BigEndian.PutUint32(u[0:], uint32(timeNow>>28)) // set time_high
|
||||
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>12)) // set time_mid
|
||||
binary.BigEndian.PutUint16(u[6:], uint16(timeNow&0xfff)) // set time_low (minus four version bits)
|
||||
binary.BigEndian.PutUint16(u[8:], clockSeq&0x3fff) // set clk_seq_hi_res (minus two variant bits)
|
||||
|
||||
u.SetVersion(V6)
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// getClockSequence returns the epoch and clock sequence for V1,V6 and V7 UUIDs.
|
||||
//
|
||||
// When useUnixTSMs is false, it uses the Coordinated Universal Time (UTC) as a count of 100-
|
||||
//
|
||||
// nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian reform to the Christian calendar).
|
||||
func (g *Gen) getClockSequence(useUnixTSMs bool) (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
|
||||
}
|
||||
|
||||
g.storageMutex.Lock()
|
||||
defer g.storageMutex.Unlock()
|
||||
|
||||
var timeNow uint64
|
||||
if useUnixTSMs {
|
||||
timeNow = uint64(g.epochFunc().UnixMilli())
|
||||
} else {
|
||||
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, nil
|
||||
}
|
||||
|
||||
// NewV7 returns a k-sortable UUID based on the current millisecond precision
|
||||
// UNIX epoch and 74 bits of pseudorandom data.
|
||||
//
|
||||
// This is implemented based on revision 04 of the Peabody UUID draft, and may
|
||||
// be subject to change pending further revisions. Until the final specification
|
||||
// revision is finished, changes required to implement updates to the spec will
|
||||
// not be considered a breaking change. They will happen as a minor version
|
||||
// releases until the spec is final.
|
||||
func (g *Gen) NewV7() (UUID, error) {
|
||||
var u UUID
|
||||
/* https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html#name-uuid-version-7
|
||||
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 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
|
||||
|
||||
ms, clockSeq, err := g.getClockSequence(true)
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
//UUIDv7 features a 48 bit timestamp. First 32bit (4bytes) represents seconds since 1970, followed by 2 bytes for the ms granularity.
|
||||
u[0] = byte(ms >> 40) //1-6 bytes: big-endian unsigned number of Unix epoch timestamp
|
||||
u[1] = byte(ms >> 32)
|
||||
u[2] = byte(ms >> 24)
|
||||
u[3] = byte(ms >> 16)
|
||||
u[4] = byte(ms >> 8)
|
||||
u[5] = byte(ms)
|
||||
|
||||
//support batching by using a monotonic pseudo-random sequence
|
||||
//The 6th byte contains the version and partially rand_a data.
|
||||
//We will lose the most significant bites from the clockSeq (with SetVersion), but it is ok, we need the least significant that contains the counter to ensure the monotonic property
|
||||
binary.BigEndian.PutUint16(u[6:8], clockSeq) // set rand_a with clock seq which is random and monotonic
|
||||
|
||||
//override first 4bits of u[6].
|
||||
u.SetVersion(V7)
|
||||
|
||||
//set rand_b 64bits of pseudo-random bits (first 2 will be overridden)
|
||||
if _, err = io.ReadFull(g.rand, u[8:16]); err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
//override first 2 bits of byte[8] for the variant
|
||||
u.SetVariant(VariantRFC4122)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// Returns the hardware address.
|
||||
func (g *Gen) getHardwareAddr() ([]byte, error) {
|
||||
var err error
|
||||
g.hardwareAddrOnce.Do(func() {
|
||||
var hwAddr net.HardwareAddr
|
||||
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 the difference between UUID epoch (October 15, 1582)
|
||||
// and current time in 100-nanosecond intervals.
|
||||
func (g *Gen) getEpoch() uint64 {
|
||||
return epochStart + uint64(g.epochFunc().UnixNano()/100)
|
||||
}
|
||||
|
||||
// Returns the UUID based on the hashing of the namespace UUID and name.
|
||||
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
||||
u := UUID{}
|
||||
h.Write(ns[:])
|
||||
h.Write([]byte(name))
|
||||
copy(u[:], h.Sum(nil))
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
var netInterfaces = net.Interfaces
|
||||
|
||||
// Returns the hardware address.
|
||||
func defaultHWAddrFunc() (net.HardwareAddr, error) {
|
||||
ifaces, err := netInterfaces()
|
||||
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")
|
||||
}
|
3
vendor/github.com/gofrs/uuid/v5/go.mod
generated
vendored
Normal file
3
vendor/github.com/gofrs/uuid/v5/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
module github.com/gofrs/uuid/v5
|
||||
|
||||
go 1.19
|
35
vendor/github.com/gofrs/uuid/sql.go → vendor/github.com/gofrs/uuid/v5/sql.go
generated
vendored
35
vendor/github.com/gofrs/uuid/sql.go → vendor/github.com/gofrs/uuid/v5/sql.go
generated
vendored
|
@ -22,12 +22,14 @@
|
|||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var _ driver.Valuer = UUID{}
|
||||
var _ sql.Scanner = (*UUID)(nil)
|
||||
|
||||
// Value implements the driver.Valuer interface.
|
||||
func (u UUID) Value() (driver.Value, error) {
|
||||
return u.String(), nil
|
||||
|
@ -49,7 +51,9 @@ func (u *UUID) Scan(src interface{}) error {
|
|||
return u.UnmarshalText(src)
|
||||
|
||||
case string:
|
||||
return u.UnmarshalText([]byte(src))
|
||||
uu, err := FromString(src)
|
||||
*u = uu
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
|
||||
|
@ -83,27 +87,30 @@ func (u *NullUUID) Scan(src interface{}) error {
|
|||
return u.UUID.Scan(src)
|
||||
}
|
||||
|
||||
var nullJSON = []byte("null")
|
||||
|
||||
// MarshalJSON marshals the NullUUID as null or the nested UUID
|
||||
func (u NullUUID) MarshalJSON() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return json.Marshal(nil)
|
||||
return nullJSON, nil
|
||||
}
|
||||
|
||||
return json.Marshal(u.UUID)
|
||||
var buf [38]byte
|
||||
buf[0] = '"'
|
||||
encodeCanonical(buf[1:37], u.UUID)
|
||||
buf[37] = '"'
|
||||
return buf[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a NullUUID
|
||||
func (u *NullUUID) UnmarshalJSON(b []byte) error {
|
||||
if bytes.Equal(b, []byte("null")) {
|
||||
if string(b) == "null" {
|
||||
u.UUID, u.Valid = Nil, false
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(b, &u.UUID); err != nil {
|
||||
return err
|
||||
if n := len(b); n >= 2 && b[0] == '"' {
|
||||
b = b[1 : n-1]
|
||||
}
|
||||
|
||||
u.Valid = true
|
||||
|
||||
return nil
|
||||
err := u.UUID.UnmarshalText(b)
|
||||
u.Valid = (err == nil)
|
||||
return err
|
||||
}
|
144
vendor/github.com/gofrs/uuid/uuid.go → vendor/github.com/gofrs/uuid/v5/uuid.go
generated
vendored
144
vendor/github.com/gofrs/uuid/uuid.go → vendor/github.com/gofrs/uuid/v5/uuid.go
generated
vendored
|
@ -19,14 +19,25 @@
|
|||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Package uuid provides implementations of the Universally Unique Identifier (UUID), as specified in RFC-4122 and DCE 1.1.
|
||||
// Package uuid provides implementations of the Universally Unique Identifier
|
||||
// (UUID), as specified in RFC-4122 and the Peabody RFC Draft (revision 03).
|
||||
//
|
||||
// RFC-4122[1] provides the specification for versions 1, 3, 4, and 5.
|
||||
// RFC-4122[1] provides the specification for versions 1, 3, 4, and 5. The
|
||||
// Peabody UUID RFC Draft[2] provides the specification for the new k-sortable
|
||||
// UUIDs, versions 6 and 7.
|
||||
//
|
||||
// DCE 1.1[2] provides the specification for version 2.
|
||||
// DCE 1.1[3] provides the specification for version 2, but version 2 support
|
||||
// was removed from this package in v4 due to some concerns with the
|
||||
// specification itself. Reading the spec, it seems that it would result in
|
||||
// generating UUIDs that aren't very unique. In having read the spec it seemed
|
||||
// that our implementation did not meet the spec. It also seems to be at-odds
|
||||
// with RFC 4122, meaning we would need quite a bit of special code to support
|
||||
// it. Lastly, there were no Version 2 implementations that we could find to
|
||||
// ensure we were understanding the specification correctly.
|
||||
//
|
||||
// [1] https://tools.ietf.org/html/rfc4122
|
||||
// [2] http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01
|
||||
// [2] https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03
|
||||
// [3] http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01
|
||||
package uuid
|
||||
|
||||
import (
|
||||
|
@ -46,10 +57,13 @@ type UUID [Size]byte
|
|||
const (
|
||||
_ byte = iota
|
||||
V1 // Version 1 (date-time and MAC address)
|
||||
V2 // Version 2 (date-time and MAC address, DCE security version)
|
||||
_ // Version 2 (date-time and MAC address, DCE security version) [removed]
|
||||
V3 // Version 3 (namespace name-based)
|
||||
V4 // Version 4 (random)
|
||||
V5 // Version 5 (namespace name-based)
|
||||
V6 // Version 6 (k-sortable timestamp and random data, field-compatible with v1) [peabody draft]
|
||||
V7 // Version 7 (k-sortable timestamp and random data) [peabody draft]
|
||||
_ // Version 8 (k-sortable timestamp, meant for custom implementations) [peabody draft] [not implemented]
|
||||
)
|
||||
|
||||
// UUID layout variants.
|
||||
|
@ -68,8 +82,8 @@ const (
|
|||
)
|
||||
|
||||
// Timestamp is the count of 100-nanosecond intervals since 00:00:00.00,
|
||||
// 15 October 1582 within a V1 UUID. This type has no meaning for V2-V5
|
||||
// UUIDs since they don't have an embedded timestamp.
|
||||
// 15 October 1582 within a V1 UUID. This type has no meaning for other
|
||||
// UUID versions since they don't have an embedded timestamp.
|
||||
type Timestamp uint64
|
||||
|
||||
const _100nsPerSecond = 10000000
|
||||
|
@ -78,6 +92,7 @@ const _100nsPerSecond = 10000000
|
|||
func (t Timestamp) Time() (time.Time, error) {
|
||||
secs := uint64(t) / _100nsPerSecond
|
||||
nsecs := 100 * (uint64(t) % _100nsPerSecond)
|
||||
|
||||
return time.Unix(int64(secs)-(epochStart/_100nsPerSecond), int64(nsecs)), nil
|
||||
}
|
||||
|
||||
|
@ -88,17 +103,33 @@ func TimestampFromV1(u UUID) (Timestamp, error) {
|
|||
err := fmt.Errorf("uuid: %s is version %d, not version 1", u, u.Version())
|
||||
return 0, err
|
||||
}
|
||||
|
||||
low := binary.BigEndian.Uint32(u[0:4])
|
||||
mid := binary.BigEndian.Uint16(u[4:6])
|
||||
hi := binary.BigEndian.Uint16(u[6:8]) & 0xfff
|
||||
|
||||
return Timestamp(uint64(low) + (uint64(mid) << 32) + (uint64(hi) << 48)), nil
|
||||
}
|
||||
|
||||
// String parse helpers.
|
||||
var (
|
||||
urnPrefix = []byte("urn:uuid:")
|
||||
byteGroups = []int{8, 4, 4, 4, 12}
|
||||
)
|
||||
// TimestampFromV6 returns the Timestamp embedded within a V6 UUID. This
|
||||
// function returns an error if the UUID is any version other than 6.
|
||||
//
|
||||
// This is implemented based on revision 03 of the Peabody UUID draft, and may
|
||||
// be subject to change pending further revisions. Until the final specification
|
||||
// revision is finished, changes required to implement updates to the spec will
|
||||
// not be considered a breaking change. They will happen as a minor version
|
||||
// releases until the spec is final.
|
||||
func TimestampFromV6(u UUID) (Timestamp, error) {
|
||||
if u.Version() != 6 {
|
||||
return 0, fmt.Errorf("uuid: %s is version %d, not version 6", u, u.Version())
|
||||
}
|
||||
|
||||
hi := binary.BigEndian.Uint32(u[0:4])
|
||||
mid := binary.BigEndian.Uint16(u[4:6])
|
||||
low := binary.BigEndian.Uint16(u[6:8]) & 0xfff
|
||||
|
||||
return Timestamp(uint64(low) + (uint64(mid) << 12) + (uint64(hi) << 28)), nil
|
||||
}
|
||||
|
||||
// Nil is the nil UUID, as specified in RFC-4122, that has all 128 bits set to
|
||||
// zero.
|
||||
|
@ -112,6 +143,11 @@ var (
|
|||
NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
||||
)
|
||||
|
||||
// IsNil returns if the UUID is equal to the nil UUID
|
||||
func (u UUID) IsNil() bool {
|
||||
return u == Nil
|
||||
}
|
||||
|
||||
// Version returns the algorithm version used to generate the UUID.
|
||||
func (u UUID) Version() byte {
|
||||
return u[6] >> 4
|
||||
|
@ -138,22 +174,81 @@ func (u UUID) Bytes() []byte {
|
|||
return u[:]
|
||||
}
|
||||
|
||||
// encodeCanonical encodes the canonical RFC-4122 form of UUID u into the
|
||||
// first 36 bytes dst.
|
||||
func encodeCanonical(dst []byte, u UUID) {
|
||||
const hextable = "0123456789abcdef"
|
||||
dst[8] = '-'
|
||||
dst[13] = '-'
|
||||
dst[18] = '-'
|
||||
dst[23] = '-'
|
||||
for i, x := range [16]byte{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
c := u[i]
|
||||
dst[x] = hextable[c>>4]
|
||||
dst[x+1] = hextable[c&0x0f]
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a canonical RFC-4122 string representation of the UUID:
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
|
||||
func (u UUID) String() string {
|
||||
buf := make([]byte, 36)
|
||||
var buf [36]byte
|
||||
encodeCanonical(buf[:], u)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
hex.Encode(buf[0:8], u[0:4])
|
||||
buf[8] = '-'
|
||||
hex.Encode(buf[9:13], u[4:6])
|
||||
buf[13] = '-'
|
||||
hex.Encode(buf[14:18], u[6:8])
|
||||
buf[18] = '-'
|
||||
hex.Encode(buf[19:23], u[8:10])
|
||||
buf[23] = '-'
|
||||
hex.Encode(buf[24:], u[10:])
|
||||
// Format implements fmt.Formatter for UUID values.
|
||||
//
|
||||
// The behavior is as follows:
|
||||
// The 'x' and 'X' verbs output only the hex digits of the UUID, using a-f for 'x' and A-F for 'X'.
|
||||
// The 'v', '+v', 's' and 'q' verbs return the canonical RFC-4122 string representation.
|
||||
// The 'S' verb returns the RFC-4122 format, but with capital hex digits.
|
||||
// The '#v' verb returns the "Go syntax" representation, which is a 16 byte array initializer.
|
||||
// All other verbs not handled directly by the fmt package (like '%p') are unsupported and will return
|
||||
// "%!verb(uuid.UUID=value)" as recommended by the fmt package.
|
||||
func (u UUID) Format(f fmt.State, c rune) {
|
||||
if c == 'v' && f.Flag('#') {
|
||||
fmt.Fprintf(f, "%#v", [Size]byte(u))
|
||||
return
|
||||
}
|
||||
switch c {
|
||||
case 'x', 'X':
|
||||
b := make([]byte, 32)
|
||||
hex.Encode(b, u[:])
|
||||
if c == 'X' {
|
||||
toUpperHex(b)
|
||||
}
|
||||
_, _ = f.Write(b)
|
||||
case 'v', 's', 'S':
|
||||
b, _ := u.MarshalText()
|
||||
if c == 'S' {
|
||||
toUpperHex(b)
|
||||
}
|
||||
_, _ = f.Write(b)
|
||||
case 'q':
|
||||
b := make([]byte, 38)
|
||||
b[0] = '"'
|
||||
encodeCanonical(b[1:], u)
|
||||
b[37] = '"'
|
||||
_, _ = f.Write(b)
|
||||
default:
|
||||
// invalid/unsupported format verb
|
||||
fmt.Fprintf(f, "%%!%c(uuid.UUID=%s)", c, u.String())
|
||||
}
|
||||
}
|
||||
|
||||
return string(buf)
|
||||
func toUpperHex(b []byte) {
|
||||
for i, c := range b {
|
||||
if 'a' <= c && c <= 'f' {
|
||||
b[i] = c - ('a' - 'A')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetVersion sets the version bits.
|
||||
|
@ -180,7 +275,8 @@ func (u *UUID) SetVariant(v byte) {
|
|||
// Must is a helper that wraps a call to a function returning (UUID, error)
|
||||
// and panics if the error is non-nil. It is intended for use in variable
|
||||
// initializations such as
|
||||
// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"))
|
||||
//
|
||||
// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"))
|
||||
func Must(u UUID, err error) UUID {
|
||||
if err != nil {
|
||||
panic(err)
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
|
@ -15,7 +15,9 @@ github.com/go-chi/chi/v5
|
|||
github.com/go-chi/chi/v5/middleware
|
||||
# github.com/gofrs/uuid v3.2.0+incompatible
|
||||
## explicit
|
||||
github.com/gofrs/uuid
|
||||
# github.com/gofrs/uuid/v5 v5.0.0
|
||||
## explicit
|
||||
github.com/gofrs/uuid/v5
|
||||
# github.com/gorilla/mux v1.7.3
|
||||
## explicit
|
||||
github.com/gorilla/mux
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue