| // 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 |
| } |