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.

uuid.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. // Package uuid provides implementation of Universally Unique Identifier (UUID).
  22. // Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
  23. // version 2 (as specified in DCE 1.1).
  24. package uuid
  25. import (
  26. "bytes"
  27. "encoding/hex"
  28. )
  29. // Size of a UUID in bytes.
  30. const Size = 16
  31. // UUID representation compliant with specification
  32. // described in RFC 4122.
  33. type UUID [Size]byte
  34. // UUID versions
  35. const (
  36. _ byte = iota
  37. V1
  38. V2
  39. V3
  40. V4
  41. V5
  42. )
  43. // UUID layout variants.
  44. const (
  45. VariantNCS byte = iota
  46. VariantRFC4122
  47. VariantMicrosoft
  48. VariantFuture
  49. )
  50. // UUID DCE domains.
  51. const (
  52. DomainPerson = iota
  53. DomainGroup
  54. DomainOrg
  55. )
  56. // String parse helpers.
  57. var (
  58. urnPrefix = []byte("urn:uuid:")
  59. byteGroups = []int{8, 4, 4, 4, 12}
  60. )
  61. // Nil is special form of UUID that is specified to have all
  62. // 128 bits set to zero.
  63. var Nil = UUID{}
  64. // Predefined namespace UUIDs.
  65. var (
  66. NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
  67. NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
  68. NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
  69. NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
  70. )
  71. // Equal returns true if u1 and u2 equals, otherwise returns false.
  72. func Equal(u1 UUID, u2 UUID) bool {
  73. return bytes.Equal(u1[:], u2[:])
  74. }
  75. // Version returns algorithm version used to generate UUID.
  76. func (u UUID) Version() byte {
  77. return u[6] >> 4
  78. }
  79. // Variant returns UUID layout variant.
  80. func (u UUID) Variant() byte {
  81. switch {
  82. case (u[8] >> 7) == 0x00:
  83. return VariantNCS
  84. case (u[8] >> 6) == 0x02:
  85. return VariantRFC4122
  86. case (u[8] >> 5) == 0x06:
  87. return VariantMicrosoft
  88. case (u[8] >> 5) == 0x07:
  89. fallthrough
  90. default:
  91. return VariantFuture
  92. }
  93. }
  94. // Bytes returns bytes slice representation of UUID.
  95. func (u UUID) Bytes() []byte {
  96. return u[:]
  97. }
  98. // Returns canonical string representation of UUID:
  99. // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  100. func (u UUID) String() string {
  101. buf := make([]byte, 36)
  102. hex.Encode(buf[0:8], u[0:4])
  103. buf[8] = '-'
  104. hex.Encode(buf[9:13], u[4:6])
  105. buf[13] = '-'
  106. hex.Encode(buf[14:18], u[6:8])
  107. buf[18] = '-'
  108. hex.Encode(buf[19:23], u[8:10])
  109. buf[23] = '-'
  110. hex.Encode(buf[24:], u[10:])
  111. return string(buf)
  112. }
  113. // SetVersion sets version bits.
  114. func (u *UUID) SetVersion(v byte) {
  115. u[6] = (u[6] & 0x0f) | (v << 4)
  116. }
  117. // SetVariant sets variant bits.
  118. func (u *UUID) SetVariant(v byte) {
  119. switch v {
  120. case VariantNCS:
  121. u[8] = (u[8]&(0xff>>1) | (0x00 << 7))
  122. case VariantRFC4122:
  123. u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
  124. case VariantMicrosoft:
  125. u[8] = (u[8]&(0xff>>3) | (0x06 << 5))
  126. case VariantFuture:
  127. fallthrough
  128. default:
  129. u[8] = (u[8]&(0xff>>3) | (0x07 << 5))
  130. }
  131. }
  132. // Must is a helper that wraps a call to a function returning (UUID, error)
  133. // and panics if the error is non-nil. It is intended for use in variable
  134. // initializations such as
  135. // var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"));
  136. func Must(u UUID, err error) UUID {
  137. if err != nil {
  138. panic(err)
  139. }
  140. return u
  141. }