1// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru> 2// 3// Permission is hereby granted, free of charge, to any person obtaining 4// a copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to 8// permit persons to whom the Software is furnished to do so, subject to 9// the following conditions: 10// 11// The above copyright notice and this permission notice shall be 12// included in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22// Package uuid provides implementation of Universally Unique Identifier (UUID). 23// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and 24// version 2 (as specified in DCE 1.1). 25package uuid 26 27import ( 28 "bytes" 29 "encoding/hex" 30) 31 32// Size of a UUID in bytes. 33const Size = 16 34 35// UUID representation compliant with specification 36// described in RFC 4122. 37type UUID [Size]byte 38 39// UUID versions 40const ( 41 _ byte = iota 42 V1 43 V2 44 V3 45 V4 46 V5 47) 48 49// UUID layout variants. 50const ( 51 VariantNCS byte = iota 52 VariantRFC4122 53 VariantMicrosoft 54 VariantFuture 55) 56 57// UUID DCE domains. 58const ( 59 DomainPerson = iota 60 DomainGroup 61 DomainOrg 62) 63 64// String parse helpers. 65var ( 66 urnPrefix = []byte("urn:uuid:") 67 byteGroups = []int{8, 4, 4, 4, 12} 68) 69 70// Nil is special form of UUID that is specified to have all 71// 128 bits set to zero. 72var Nil = UUID{} 73 74// Predefined namespace UUIDs. 75var ( 76 NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) 77 NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) 78 NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) 79 NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) 80) 81 82// Equal returns true if u1 and u2 equals, otherwise returns false. 83func Equal(u1 UUID, u2 UUID) bool { 84 return bytes.Equal(u1[:], u2[:]) 85} 86 87// Version returns algorithm version used to generate UUID. 88func (u UUID) Version() byte { 89 return u[6] >> 4 90} 91 92// Variant returns UUID layout variant. 93func (u UUID) Variant() byte { 94 switch { 95 case (u[8] >> 7) == 0x00: 96 return VariantNCS 97 case (u[8] >> 6) == 0x02: 98 return VariantRFC4122 99 case (u[8] >> 5) == 0x06: 100 return VariantMicrosoft 101 case (u[8] >> 5) == 0x07: 102 fallthrough 103 default: 104 return VariantFuture 105 } 106} 107 108// Bytes returns bytes slice representation of UUID. 109func (u UUID) Bytes() []byte { 110 return u[:] 111} 112 113// Returns canonical string representation of UUID: 114// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. 115func (u UUID) String() string { 116 buf := make([]byte, 36) 117 118 hex.Encode(buf[0:8], u[0:4]) 119 buf[8] = '-' 120 hex.Encode(buf[9:13], u[4:6]) 121 buf[13] = '-' 122 hex.Encode(buf[14:18], u[6:8]) 123 buf[18] = '-' 124 hex.Encode(buf[19:23], u[8:10]) 125 buf[23] = '-' 126 hex.Encode(buf[24:], u[10:]) 127 128 return string(buf) 129} 130 131// SetVersion sets version bits. 132func (u *UUID) SetVersion(v byte) { 133 u[6] = (u[6] & 0x0f) | (v << 4) 134} 135 136// SetVariant sets variant bits. 137func (u *UUID) SetVariant(v byte) { 138 switch v { 139 case VariantNCS: 140 u[8] = (u[8]&(0xff>>1) | (0x00 << 7)) 141 case VariantRFC4122: 142 u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) 143 case VariantMicrosoft: 144 u[8] = (u[8]&(0xff>>3) | (0x06 << 5)) 145 case VariantFuture: 146 fallthrough 147 default: 148 u[8] = (u[8]&(0xff>>3) | (0x07 << 5)) 149 } 150} 151 152// Must is a helper that wraps a call to a function returning (UUID, error) 153// and panics if the error is non-nil. It is intended for use in variable 154// initializations such as 155// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")); 156func Must(u UUID, err error) UUID { 157 if err != nil { 158 panic(err) 159 } 160 return u 161} 162