2019-03-27 12:15:23 +01:00
|
|
|
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
|
2016-11-03 23:16:01 +01:00
|
|
|
//
|
|
|
|
// 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 provides implementation of Universally Unique Identifier (UUID).
|
|
|
|
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
|
|
|
|
// version 2 (as specified in DCE 1.1).
|
|
|
|
package uuid
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/hex"
|
2019-03-27 12:15:23 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Size of a UUID in bytes.
|
|
|
|
const Size = 16
|
|
|
|
|
|
|
|
// UUID representation compliant with specification
|
|
|
|
// described in RFC 4122.
|
|
|
|
type UUID [Size]byte
|
|
|
|
|
|
|
|
// UUID versions
|
|
|
|
const (
|
|
|
|
_ byte = iota
|
|
|
|
V1
|
|
|
|
V2
|
|
|
|
V3
|
|
|
|
V4
|
|
|
|
V5
|
2016-11-03 23:16:01 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// UUID layout variants.
|
|
|
|
const (
|
2019-03-27 12:15:23 +01:00
|
|
|
VariantNCS byte = iota
|
2016-11-03 23:16:01 +01:00
|
|
|
VariantRFC4122
|
|
|
|
VariantMicrosoft
|
|
|
|
VariantFuture
|
|
|
|
)
|
|
|
|
|
|
|
|
// UUID DCE domains.
|
|
|
|
const (
|
|
|
|
DomainPerson = iota
|
|
|
|
DomainGroup
|
|
|
|
DomainOrg
|
|
|
|
)
|
|
|
|
|
|
|
|
// String parse helpers.
|
|
|
|
var (
|
|
|
|
urnPrefix = []byte("urn:uuid:")
|
|
|
|
byteGroups = []int{8, 4, 4, 4, 12}
|
|
|
|
)
|
|
|
|
|
2019-03-27 12:15:23 +01:00
|
|
|
// Nil is special form of UUID that is specified to have all
|
2016-11-03 23:16:01 +01:00
|
|
|
// 128 bits set to zero.
|
|
|
|
var Nil = UUID{}
|
|
|
|
|
|
|
|
// Predefined namespace UUIDs.
|
|
|
|
var (
|
2019-03-27 12:15:23 +01:00
|
|
|
NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
|
|
|
|
NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
|
|
|
|
NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
|
|
|
|
NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
2016-11-03 23:16:01 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Equal returns true if u1 and u2 equals, otherwise returns false.
|
|
|
|
func Equal(u1 UUID, u2 UUID) bool {
|
|
|
|
return bytes.Equal(u1[:], u2[:])
|
|
|
|
}
|
|
|
|
|
|
|
|
// Version returns algorithm version used to generate UUID.
|
2019-03-27 12:15:23 +01:00
|
|
|
func (u UUID) Version() byte {
|
|
|
|
return u[6] >> 4
|
2016-11-03 23:16:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Variant returns UUID layout variant.
|
2019-03-27 12:15:23 +01:00
|
|
|
func (u UUID) Variant() byte {
|
2016-11-03 23:16:01 +01:00
|
|
|
switch {
|
2019-03-27 12:15:23 +01:00
|
|
|
case (u[8] >> 7) == 0x00:
|
2016-11-03 23:16:01 +01:00
|
|
|
return VariantNCS
|
2019-03-27 12:15:23 +01:00
|
|
|
case (u[8] >> 6) == 0x02:
|
2016-11-03 23:16:01 +01:00
|
|
|
return VariantRFC4122
|
2019-03-27 12:15:23 +01:00
|
|
|
case (u[8] >> 5) == 0x06:
|
2016-11-03 23:16:01 +01:00
|
|
|
return VariantMicrosoft
|
2019-03-27 12:15:23 +01:00
|
|
|
case (u[8] >> 5) == 0x07:
|
|
|
|
fallthrough
|
|
|
|
default:
|
|
|
|
return VariantFuture
|
2016-11-03 23:16:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bytes returns bytes slice representation of UUID.
|
|
|
|
func (u UUID) Bytes() []byte {
|
|
|
|
return u[:]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns canonical string representation of UUID:
|
|
|
|
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
|
|
|
|
func (u UUID) String() string {
|
|
|
|
buf := make([]byte, 36)
|
|
|
|
|
|
|
|
hex.Encode(buf[0:8], u[0:4])
|
2019-03-27 12:15:23 +01:00
|
|
|
buf[8] = '-'
|
2016-11-03 23:16:01 +01:00
|
|
|
hex.Encode(buf[9:13], u[4:6])
|
2019-03-27 12:15:23 +01:00
|
|
|
buf[13] = '-'
|
2016-11-03 23:16:01 +01:00
|
|
|
hex.Encode(buf[14:18], u[6:8])
|
2019-03-27 12:15:23 +01:00
|
|
|
buf[18] = '-'
|
2016-11-03 23:16:01 +01:00
|
|
|
hex.Encode(buf[19:23], u[8:10])
|
2019-03-27 12:15:23 +01:00
|
|
|
buf[23] = '-'
|
2016-11-03 23:16:01 +01:00
|
|
|
hex.Encode(buf[24:], u[10:])
|
|
|
|
|
|
|
|
return string(buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetVersion sets version bits.
|
|
|
|
func (u *UUID) SetVersion(v byte) {
|
|
|
|
u[6] = (u[6] & 0x0f) | (v << 4)
|
|
|
|
}
|
|
|
|
|
2019-03-27 12:15:23 +01:00
|
|
|
// SetVariant sets variant bits.
|
|
|
|
func (u *UUID) SetVariant(v byte) {
|
|
|
|
switch v {
|
|
|
|
case VariantNCS:
|
|
|
|
u[8] = (u[8]&(0xff>>1) | (0x00 << 7))
|
|
|
|
case VariantRFC4122:
|
|
|
|
u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
|
|
|
|
case VariantMicrosoft:
|
|
|
|
u[8] = (u[8]&(0xff>>3) | (0x06 << 5))
|
|
|
|
case VariantFuture:
|
|
|
|
fallthrough
|
|
|
|
default:
|
|
|
|
u[8] = (u[8]&(0xff>>3) | (0x07 << 5))
|
2016-11-03 23:16:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 12:15:23 +01:00
|
|
|
// 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"));
|
|
|
|
func Must(u UUID, err error) UUID {
|
2016-11-03 23:16:01 +01:00
|
|
|
if err != nil {
|
2019-03-27 12:15:23 +01:00
|
|
|
panic(err)
|
2016-11-03 23:16:01 +01:00
|
|
|
}
|
|
|
|
return u
|
|
|
|
}
|