Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.1 KiB
161 lines
4.1 KiB
// 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 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" |
|
) |
|
|
|
// 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 |
|
) |
|
|
|
// UUID layout variants. |
|
const ( |
|
VariantNCS byte = iota |
|
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} |
|
) |
|
|
|
// Nil is special form of UUID that is specified to have all |
|
// 128 bits set to zero. |
|
var Nil = UUID{} |
|
|
|
// Predefined namespace UUIDs. |
|
var ( |
|
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")) |
|
) |
|
|
|
// 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. |
|
func (u UUID) Version() byte { |
|
return u[6] >> 4 |
|
} |
|
|
|
// Variant returns UUID layout variant. |
|
func (u UUID) Variant() byte { |
|
switch { |
|
case (u[8] >> 7) == 0x00: |
|
return VariantNCS |
|
case (u[8] >> 6) == 0x02: |
|
return VariantRFC4122 |
|
case (u[8] >> 5) == 0x06: |
|
return VariantMicrosoft |
|
case (u[8] >> 5) == 0x07: |
|
fallthrough |
|
default: |
|
return VariantFuture |
|
} |
|
} |
|
|
|
// 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]) |
|
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:]) |
|
|
|
return string(buf) |
|
} |
|
|
|
// SetVersion sets version bits. |
|
func (u *UUID) SetVersion(v byte) { |
|
u[6] = (u[6] & 0x0f) | (v << 4) |
|
} |
|
|
|
// 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)) |
|
} |
|
} |
|
|
|
// 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 { |
|
if err != nil { |
|
panic(err) |
|
} |
|
return u |
|
}
|
|
|