Codebase list golang-github-gofrs-uuid / cb76034
New upstream release. Debian Janitor 2 years ago
8 changed file(s) with 125 addition(s) and 111 deletion(s). Raw diff Collapse all Expand all
55 - 1.9.x
66 - 1.10.x
77 - 1.11.x
8 - 1.12.x
89 - tip
910 matrix:
1011 allow_failures:
1112 - go: tip
1213 fast_finish: true
13 env:
14 - GO111MODULE=on
1514 before_install:
1615 - go get golang.org/x/tools/cmd/cover
1716 script:
1111
1212 This package supports the following UUID versions:
1313 * Version 1, based on timestamp and MAC address (RFC-4122)
14 * Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
1514 * Version 3, based on MD5 hashing of a named value (RFC-4122)
1615 * Version 4, based on random numbers (RFC-4122)
1716 * Version 5, based on SHA-1 hashing of a named value (RFC-4122)
113113 case 41, 45:
114114 return u.decodeURN(text)
115115 default:
116 return fmt.Errorf("uuid: incorrect UUID length: %s", text)
116 return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(text), text)
117117 }
118118 }
119119
121121 // "6ba7b810-9dad-11d1-80b4-00c04fd430c8".
122122 func (u *UUID) decodeCanonical(t []byte) error {
123123 if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' {
124 return fmt.Errorf("uuid: incorrect UUID format %s", t)
124 return fmt.Errorf("uuid: incorrect UUID format in string %q", t)
125125 }
126126
127127 src := t
159159 l := len(t)
160160
161161 if t[0] != '{' || t[l-1] != '}' {
162 return fmt.Errorf("uuid: incorrect UUID format %s", t)
162 return fmt.Errorf("uuid: incorrect UUID format in string %q", t)
163163 }
164164
165165 return u.decodePlain(t[1 : l-1])
174174 urnUUIDPrefix := t[:9]
175175
176176 if !bytes.Equal(urnUUIDPrefix, urnPrefix) {
177 return fmt.Errorf("uuid: incorrect UUID format: %s", t)
177 return fmt.Errorf("uuid: incorrect UUID format in string %q", t)
178178 }
179179
180180 return u.decodePlain(t[9:total])
190190 case 36:
191191 return u.decodeCanonical(t)
192192 default:
193 return fmt.Errorf("uuid: incorrect UUID length: %s", t)
193 return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(t), t)
194194 }
195195 }
196196
0 golang-github-gofrs-uuid (4.0.0-1) UNRELEASED; urgency=low
1
2 * New upstream release.
3
4 -- Debian Janitor <janitor@jelmer.uk> Sun, 03 Oct 2021 11:08:01 -0000
5
06 golang-github-gofrs-uuid (3.2.0-2) unstable; urgency=medium
17
28 * Standards-Version: 4.4.1
2929 "hash"
3030 "io"
3131 "net"
32 "os"
3332 "sync"
3433 "time"
3534 )
4645 // DefaultGenerator is the default UUID Generator used by this package.
4746 var DefaultGenerator Generator = NewGen()
4847
49 var (
50 posixUID = uint32(os.Getuid())
51 posixGID = uint32(os.Getgid())
52 )
53
5448 // NewV1 returns a UUID based on the current timestamp and MAC address.
5549 func NewV1() (UUID, error) {
5650 return DefaultGenerator.NewV1()
5751 }
5852
59 // NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
60 func NewV2(domain byte) (UUID, error) {
61 return DefaultGenerator.NewV2(domain)
62 }
63
6453 // NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
6554 func NewV3(ns UUID, name string) UUID {
6655 return DefaultGenerator.NewV3(ns, name)
7968 // Generator provides an interface for generating UUIDs.
8069 type Generator interface {
8170 NewV1() (UUID, error)
82 NewV2(domain byte) (UUID, error)
8371 NewV3(ns UUID, name string) UUID
8472 NewV4() (UUID, error)
8573 NewV5(ns UUID, name string) UUID
163151 return u, nil
164152 }
165153
166 // NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
167 func (g *Gen) NewV2(domain byte) (UUID, error) {
168 u, err := g.NewV1()
169 if err != nil {
170 return Nil, err
171 }
172
173 switch domain {
174 case DomainPerson:
175 binary.BigEndian.PutUint32(u[:], posixUID)
176 case DomainGroup:
177 binary.BigEndian.PutUint32(u[:], posixGID)
178 }
179
180 u[9] = domain
181
182 u.SetVersion(V2)
183 u.SetVariant(VariantRFC4122)
184
185 return u, nil
186 }
187
188154 // NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
189155 func (g *Gen) NewV3(ns UUID, name string) UUID {
190156 u := newFromHash(md5.New(), ns, name)
215181 return u
216182 }
217183
218 // Returns the epoch and clock sequence.
184 // getClockSequence returns the epoch and clock sequence.
219185 func (g *Gen) getClockSequence() (uint64, uint16, error) {
220186 var err error
221187 g.clockSequenceOnce.Do(func() {
3131
3232 func TestGenerator(t *testing.T) {
3333 t.Run("NewV1", testNewV1)
34 t.Run("NewV2", testNewV2)
3534 t.Run("NewV3", testNewV3)
3635 t.Run("NewV4", testNewV4)
3736 t.Run("NewV5", testNewV5)
170169 }
171170 }
172171
173 func testNewV2(t *testing.T) {
174 t.Run("Basic", testNewV2Basic)
175 t.Run("DifferentAcrossCalls", testNewV2DifferentAcrossCalls)
176 t.Run("FaultyRand", testNewV2FaultyRand)
177 }
178
179 func testNewV2Basic(t *testing.T) {
180 domains := []byte{
181 DomainPerson,
182 DomainGroup,
183 DomainOrg,
184 }
185 for _, domain := range domains {
186 u, err := NewV2(domain)
187 if err != nil {
188 t.Errorf("NewV2(%d): %v", domain, err)
189 }
190 if got, want := u.Version(), V2; got != want {
191 t.Errorf("NewV2(%d) generated UUID with version %d, want %d", domain, got, want)
192 }
193 if got, want := u.Variant(), VariantRFC4122; got != want {
194 t.Errorf("NewV2(%d) generated UUID with variant %d, want %d", domain, got, want)
195 }
196 }
197 }
198
199 func testNewV2DifferentAcrossCalls(t *testing.T) {
200 u1, err := NewV2(DomainOrg)
201 if err != nil {
202 t.Fatal(err)
203 }
204 u2, err := NewV2(DomainOrg)
205 if err != nil {
206 t.Fatal(err)
207 }
208 if u1 == u2 {
209 t.Errorf("generated identical UUIDs across calls: %v", u1)
210 }
211 }
212
213 func testNewV2FaultyRand(t *testing.T) {
214 g := &Gen{
215 epochFunc: time.Now,
216 hwAddrFunc: defaultHWAddrFunc,
217 rand: &faultyReader{
218 readToFail: 0, // fail immediately
219 },
220 }
221 u, err := g.NewV2(DomainPerson)
222 if err == nil {
223 t.Fatalf("got %v, want error", u)
224 }
225 if u != Nil {
226 t.Fatalf("got %v on error, want Nil", u)
227 }
228 }
229
230172 func testNewV3(t *testing.T) {
231173 t.Run("Basic", testNewV3Basic)
232174 t.Run("EqualNames", testNewV3EqualNames)
379321 b.Run("NewV1", func(b *testing.B) {
380322 for i := 0; i < b.N; i++ {
381323 NewV1()
382 }
383 })
384 b.Run("NewV2", func(b *testing.B) {
385 for i := 0; i < b.N; i++ {
386 NewV2(DomainOrg)
387324 }
388325 })
389326 b.Run("NewV3", func(b *testing.B) {
1818 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1919 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2020
21 // Package uuid provides implementations of the Universally Unique Identifier (UUID), as specified in RFC-4122 and DCE 1.1.
21 // Package uuid provides implementations of the Universally Unique Identifier
22 // (UUID), as specified in RFC-4122,
2223 //
2324 // RFC-4122[1] provides the specification for versions 1, 3, 4, and 5.
2425 //
25 // DCE 1.1[2] provides the specification for version 2.
26 // DCE 1.1[2] provides the specification for version 2, but version 2 support
27 // was removed from this package in v4 due to some concerns with the
28 // specification itself. Reading the spec, it seems that it would result in
29 // generating UUIDs that aren't very unique. In having read the spec it seemed
30 // that our implementation did not meet the spec. It also seems to be at-odds
31 // with RFC 4122, meaning we would need quite a bit of special code to support
32 // it. Lastly, there were no Version 2 implementations that we could find to
33 // ensure we were understanding the specification correctly.
2634 //
2735 // [1] https://tools.ietf.org/html/rfc4122
2836 // [2] http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01
3240 "encoding/binary"
3341 "encoding/hex"
3442 "fmt"
43 "io"
44 "strings"
3545 "time"
3646 )
3747
4555 const (
4656 _ byte = iota
4757 V1 // Version 1 (date-time and MAC address)
48 V2 // Version 2 (date-time and MAC address, DCE security version)
58 _ // Version 2 (date-time and MAC address, DCE security version) [removed]
4959 V3 // Version 3 (namespace name-based)
5060 V4 // Version 4 (random)
5161 V5 // Version 5 (namespace name-based)
6777 )
6878
6979 // Timestamp is the count of 100-nanosecond intervals since 00:00:00.00,
70 // 15 October 1582 within a V1 UUID. This type has no meaning for V2-V5
71 // UUIDs since they don't have an embedded timestamp.
80 // 15 October 1582 within a V1 UUID. This type has no meaning for other
81 // UUID versions since they don't have an embedded timestamp.
7282 type Timestamp uint64
7383
7484 const _100nsPerSecond = 10000000
155165 return string(buf)
156166 }
157167
168 // Format implements fmt.Formatter for UUID values.
169 //
170 // The behavior is as follows:
171 // The 'x' and 'X' verbs output only the hex digits of the UUID, using a-f for 'x' and A-F for 'X'.
172 // The 'v', '+v', 's' and 'q' verbs return the canonical RFC-4122 string representation.
173 // The 'S' verb returns the RFC-4122 format, but with capital hex digits.
174 // The '#v' verb returns the "Go syntax" representation, which is a 16 byte array initializer.
175 // All other verbs not handled directly by the fmt package (like '%p') are unsupported and will return
176 // "%!verb(uuid.UUID=value)" as recommended by the fmt package.
177 func (u UUID) Format(f fmt.State, c rune) {
178 switch c {
179 case 'x', 'X':
180 s := hex.EncodeToString(u.Bytes())
181 if c == 'X' {
182 s = strings.Map(toCapitalHexDigits, s)
183 }
184 _, _ = io.WriteString(f, s)
185 case 'v':
186 var s string
187 if f.Flag('#') {
188 s = fmt.Sprintf("%#v", [Size]byte(u))
189 } else {
190 s = u.String()
191 }
192 _, _ = io.WriteString(f, s)
193 case 's', 'S':
194 s := u.String()
195 if c == 'S' {
196 s = strings.Map(toCapitalHexDigits, s)
197 }
198 _, _ = io.WriteString(f, s)
199 case 'q':
200 _, _ = io.WriteString(f, `"`+u.String()+`"`)
201 default:
202 // invalid/unsupported format verb
203 fmt.Fprintf(f, "%%!%c(uuid.UUID=%s)", c, u.String())
204 }
205 }
206
207 func toCapitalHexDigits(ch rune) rune {
208 // convert a-f hex digits to A-F
209 switch ch {
210 case 'a':
211 return 'A'
212 case 'b':
213 return 'B'
214 case 'c':
215 return 'C'
216 case 'd':
217 return 'D'
218 case 'e':
219 return 'E'
220 case 'f':
221 return 'F'
222 default:
223 return ch
224 }
225 }
226
158227 // SetVersion sets the version bits.
159228 func (u *UUID) SetVersion(v byte) {
160229 u[6] = (u[6] & 0x0f) | (v << 4)
3434 t.Run("Variant", testUUIDVariant)
3535 t.Run("SetVersion", testUUIDSetVersion)
3636 t.Run("SetVariant", testUUIDSetVariant)
37 t.Run("Format", testUUIDFormat)
3738 }
3839
3940 func testUUIDBytes(t *testing.T) {
109110 u.SetVariant(want)
110111 if got := u.Variant(); got != want {
111112 t.Errorf("%v.Variant() == %d after SetVariant(%d)", u, got, want)
113 }
114 }
115 }
116
117 func testUUIDFormat(t *testing.T) {
118 val := Must(FromString("12345678-90ab-cdef-1234-567890abcdef"))
119 tests := []struct {
120 u UUID
121 f string
122 want string
123 }{
124 {u: val, f: "%s", want: "12345678-90ab-cdef-1234-567890abcdef"},
125 {u: val, f: "%S", want: "12345678-90AB-CDEF-1234-567890ABCDEF"},
126 {u: val, f: "%q", want: `"12345678-90ab-cdef-1234-567890abcdef"`},
127 {u: val, f: "%x", want: "1234567890abcdef1234567890abcdef"},
128 {u: val, f: "%X", want: "1234567890ABCDEF1234567890ABCDEF"},
129 {u: val, f: "%v", want: "12345678-90ab-cdef-1234-567890abcdef"},
130 {u: val, f: "%+v", want: "12345678-90ab-cdef-1234-567890abcdef"},
131 {u: val, f: "%#v", want: "[16]uint8{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef}"},
132 {u: val, f: "%T", want: "uuid.UUID"},
133 {u: val, f: "%t", want: "%!t(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
134 {u: val, f: "%b", want: "%!b(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
135 {u: val, f: "%c", want: "%!c(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
136 {u: val, f: "%d", want: "%!d(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
137 {u: val, f: "%e", want: "%!e(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
138 {u: val, f: "%E", want: "%!E(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
139 {u: val, f: "%f", want: "%!f(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
140 {u: val, f: "%F", want: "%!F(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
141 {u: val, f: "%g", want: "%!g(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
142 {u: val, f: "%G", want: "%!G(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
143 {u: val, f: "%o", want: "%!o(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
144 {u: val, f: "%U", want: "%!U(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
145 }
146 for _, tt := range tests {
147 got := fmt.Sprintf(tt.f, tt.u)
148 if tt.want != got {
149 t.Errorf(`Format("%s") got %s, want %s`, tt.f, got, tt.want)
112150 }
113151 }
114152 }