From f2aec0ce722f8d6e79fa43042bfc55712b9fbb95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 00:31:22 +0000 Subject: [PATCH] Bump github.com/lithammer/shortuuid/v4 from 4.0.0 to 4.2.0 Bumps [github.com/lithammer/shortuuid/v4](https://github.com/lithammer/shortuuid) from 4.0.0 to 4.2.0. - [Release notes](https://github.com/lithammer/shortuuid/releases) - [Commits](https://github.com/lithammer/shortuuid/compare/v4.0.0...v4.2.0) --- updated-dependencies: - dependency-name: github.com/lithammer/shortuuid/v4 dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +- go.sum | 9 +- vendor/github.com/google/uuid/.travis.yml | 9 - vendor/github.com/google/uuid/CHANGELOG.md | 41 +++++ vendor/github.com/google/uuid/CONTRIBUTING.md | 16 ++ vendor/github.com/google/uuid/README.md | 10 +- vendor/github.com/google/uuid/hash.go | 6 + vendor/github.com/google/uuid/node_js.go | 2 +- vendor/github.com/google/uuid/time.go | 21 ++- vendor/github.com/google/uuid/uuid.go | 89 +++++++++- vendor/github.com/google/uuid/version6.go | 56 +++++++ vendor/github.com/google/uuid/version7.go | 104 ++++++++++++ .../lithammer/shortuuid/v4/README.md | 12 +- .../lithammer/shortuuid/v4/alphabet.go | 67 ++++---- .../lithammer/shortuuid/v4/base57.go | 91 ---------- .../lithammer/shortuuid/v4/encoder.go | 158 ++++++++++++++++++ .../lithammer/shortuuid/v4/shortuuid.go | 12 +- vendor/modules.txt | 6 +- 18 files changed, 545 insertions(+), 170 deletions(-) delete mode 100644 vendor/github.com/google/uuid/.travis.yml create mode 100644 vendor/github.com/google/uuid/CHANGELOG.md create mode 100644 vendor/github.com/google/uuid/version6.go create mode 100644 vendor/github.com/google/uuid/version7.go delete mode 100644 vendor/github.com/lithammer/shortuuid/v4/base57.go create mode 100644 vendor/github.com/lithammer/shortuuid/v4/encoder.go diff --git a/go.mod b/go.mod index f08d44c..efa51c1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/umputun/rlb -go 1.20 +go 1.21 require ( github.com/didip/tollbooth/v7 v7.0.2 @@ -10,7 +10,7 @@ require ( github.com/go-pkgz/lgr v0.11.1 github.com/go-pkgz/rest v1.20.2 github.com/jessevdk/go-flags v1.6.1 - github.com/lithammer/shortuuid/v4 v4.0.0 + github.com/lithammer/shortuuid/v4 v4.2.0 github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -19,7 +19,7 @@ require ( github.com/ajg/form v1.5.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-pkgz/expirable-cache/v3 v3.0.0 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/sys v0.28.0 // indirect diff --git a/go.sum b/go.sum index e9eb028..bf8f9b5 100644 --- a/go.sum +++ b/go.sum @@ -19,13 +19,14 @@ github.com/go-pkgz/lgr v0.11.1 h1:hXFhZcznehI6imLhEa379oMOKFz7TQUmisAqb3oLOSM= github.com/go-pkgz/lgr v0.11.1/go.mod h1:tgDF4RXQnBfIgJqjgkv0yOeTQ3F1yewWIZkpUhHnAkU= github.com/go-pkgz/rest v1.20.2 h1:6wYWo85H7xFU09FadVKKc5LKIfIpCStBXJj9F/P4COc= github.com/go-pkgz/rest v1.20.2/go.mod h1:NC2xNN/y1rIs0PY13FowKoH8rk9RhJNJ0tTbkBg8Yks= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= -github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw7k08o4c= -github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y= +github.com/lithammer/shortuuid/v4 v4.2.0 h1:LMFOzVB3996a7b8aBuEXxqOBflbfPQAiVzkIcHO0h8c= +github.com/lithammer/shortuuid/v4 v4.2.0/go.mod h1:D5noHZ2oFw/YaKCfGy0YxyE7M0wMbezmMjPdhyEFe6Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml deleted file mode 100644 index d8156a6..0000000 --- a/vendor/github.com/google/uuid/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4.3 - - 1.5.3 - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md new file mode 100644 index 0000000..7ec5ac7 --- /dev/null +++ b/vendor/github.com/google/uuid/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16) + + +### Features + +* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3)) + + +### Bug Fixes + +* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06)) +* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6)) + +## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12) + + +### Features + +* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) + +## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) + + +### Features + +* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4)) + +### Fixes + +* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior) + +## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) + + +### Bug Fixes + +* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) + +## Changelog diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md index 04fdf09..a502fdc 100644 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -2,6 +2,22 @@ We definitely welcome patches and contribution to this project! +### Tips + +Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). + +Always try to include a test case! If it is not possible or not necessary, +please explain why in the pull request description. + +### Releasing + +Commits that would precipitate a SemVer change, as described in the Conventional +Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) +to create a release candidate pull request. Once submitted, `release-please` +will create a release. + +For tips on how to work with `release-please`, see its documentation. + ### Legal requirements In order to protect both you and ourselves, you will need to sign the diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md index f765a46..3e9a618 100644 --- a/vendor/github.com/google/uuid/README.md +++ b/vendor/github.com/google/uuid/README.md @@ -1,6 +1,6 @@ -# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) +# uuid The uuid package generates and inspects UUIDs based on -[RFC 4122](http://tools.ietf.org/html/rfc4122) +[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) and DCE 1.1: Authentication and Security Services. This package is based on the github.com/pborman/uuid package (previously named @@ -9,10 +9,12 @@ a UUID is a 16 byte array rather than a byte slice. One loss due to this change is the ability to represent an invalid UUID (vs a NIL UUID). ###### Install -`go get github.com/google/uuid` +```sh +go get github.com/google/uuid +``` ###### Documentation -[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) +[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go index b404f4b..dc60082 100644 --- a/vendor/github.com/google/uuid/hash.go +++ b/vendor/github.com/google/uuid/hash.go @@ -17,6 +17,12 @@ var ( NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) Nil UUID // empty UUID, all zeros + + // The Max UUID is special form of UUID that is specified to have all 128 bits set to 1. + Max = UUID{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + } ) // NewHash returns a new UUID derived from the hash of space concatenated with diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go index 24b78ed..b2a0bc8 100644 --- a/vendor/github.com/google/uuid/node_js.go +++ b/vendor/github.com/google/uuid/node_js.go @@ -7,6 +7,6 @@ package uuid // getHardwareInterface returns nil values for the JS version of the code. -// This remvoves the "net" dependency, because it is not used in the browser. +// This removes the "net" dependency, because it is not used in the browser. // Using the "net" library inflates the size of the transpiled JS code by 673k bytes. func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go index e6ef06c..c351129 100644 --- a/vendor/github.com/google/uuid/time.go +++ b/vendor/github.com/google/uuid/time.go @@ -108,12 +108,23 @@ func setClockSequence(seq int) { } // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1 and 2 UUIDs. +// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs. func (uuid UUID) Time() Time { - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time) + var t Time + switch uuid.Version() { + case 6: + time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110 + t = Time(time) + case 7: + time := binary.BigEndian.Uint64(uuid[:8]) + t = Time((time>>16)*10000 + g1582ns100) + default: // forward compatible + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + t = Time(time) + } + return t } // ClockSequence returns the clock sequence encoded in uuid. diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index a57207a..5232b48 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -56,11 +56,15 @@ func IsInvalidLengthError(err error) bool { return ok } -// Parse decodes s into a UUID or returns an error. Both the standard UUID -// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the -// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex -// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both +// the standard UUID forms defined in RFC 4122 +// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition, +// Parse accepts non-standard strings such as the raw hex encoding +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings, +// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are +// examined in the latter case. Parse should not be used to validate strings as +// it parses non-standard encodings as indicated above. func Parse(s string) (UUID, error) { var uuid UUID switch len(s) { @@ -69,7 +73,7 @@ func Parse(s string) (UUID, error) { // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: - if strings.ToLower(s[:9]) != "urn:uuid:" { + if !strings.EqualFold(s[:9], "urn:uuid:") { return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) } s = s[9:] @@ -101,7 +105,8 @@ func Parse(s string) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(s[x], s[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -117,7 +122,7 @@ func ParseBytes(b []byte) (UUID, error) { switch len(b) { case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) } b = b[9:] @@ -145,7 +150,8 @@ func ParseBytes(b []byte) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(b[x], b[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -180,6 +186,59 @@ func Must(uuid UUID, err error) UUID { return uuid } +// Validate returns an error if s is not a properly formatted UUID in one of the following formats: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +// It returns an error if the format is invalid, otherwise nil. +func Validate(s string) error { + switch len(s) { + // Standard UUID format + case 36: + + // UUID with "urn:uuid:" prefix + case 36 + 9: + if !strings.EqualFold(s[:9], "urn:uuid:") { + return fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // UUID enclosed in braces + case 36 + 2: + if s[0] != '{' || s[len(s)-1] != '}' { + return fmt.Errorf("invalid bracketed UUID format") + } + s = s[1 : len(s)-1] + + // UUID without hyphens + case 32: + for i := 0; i < len(s); i += 2 { + _, ok := xtob(s[i], s[i+1]) + if !ok { + return errors.New("invalid UUID format") + } + } + + default: + return invalidLengthError{len(s)} + } + + // Check for standard UUID format + if len(s) == 36 { + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return errors.New("invalid UUID format") + } + for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { + if _, ok := xtob(s[x], s[x+1]); !ok { + return errors.New("invalid UUID format") + } + } + } + + return nil +} + // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // , or "" if uuid is invalid. func (uuid UUID) String() string { @@ -292,3 +351,15 @@ func DisableRandPool() { poolMu.Lock() poolPos = randPoolSize } + +// UUIDs is a slice of UUID types. +type UUIDs []UUID + +// Strings returns a string slice containing the string form of each UUID in uuids. +func (uuids UUIDs) Strings() []string { + var uuidStrs = make([]string, len(uuids)) + for i, uuid := range uuids { + uuidStrs[i] = uuid.String() + } + return uuidStrs +} diff --git a/vendor/github.com/google/uuid/version6.go b/vendor/github.com/google/uuid/version6.go new file mode 100644 index 0000000..339a959 --- /dev/null +++ b/vendor/github.com/google/uuid/version6.go @@ -0,0 +1,56 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "encoding/binary" + +// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. +// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. +// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 +// +// NewV6 returns a Version 6 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewV6 returns Nil and an error. +func NewV6() (UUID, error) { + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_high | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_mid | time_low_and_version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |clk_seq_hi_res | clk_seq_low | node (0-1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | node (2-5) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + binary.BigEndian.PutUint64(uuid[0:], uint64(now)) + binary.BigEndian.PutUint16(uuid[8:], seq) + + uuid[6] = 0x60 | (uuid[6] & 0x0F) + uuid[8] = 0x80 | (uuid[8] & 0x3F) + + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + copy(uuid[10:], nodeID[:]) + nodeMu.Unlock() + + return uuid, nil +} diff --git a/vendor/github.com/google/uuid/version7.go b/vendor/github.com/google/uuid/version7.go new file mode 100644 index 0000000..3167b64 --- /dev/null +++ b/vendor/github.com/google/uuid/version7.go @@ -0,0 +1,104 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// UUID version 7 features a time-ordered value field derived from the widely +// implemented and well known Unix Epoch timestamp source, +// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. +// As well as improved entropy characteristics over versions 1 or 6. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 +// +// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. +// +// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). +// Uses the randomness pool if it was enabled with EnableRandPool. +// On error, NewV7 returns Nil and an error +func NewV7() (UUID, error) { + uuid, err := NewRandom() + if err != nil { + return uuid, err + } + makeV7(uuid[:]) + return uuid, nil +} + +// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). +// it use NewRandomFromReader fill random bits. +// On error, NewV7FromReader returns Nil and an error. +func NewV7FromReader(r io.Reader) (UUID, error) { + uuid, err := NewRandomFromReader(r) + if err != nil { + return uuid, err + } + + makeV7(uuid[:]) + return uuid, nil +} + +// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) +// uuid[8] already has the right version number (Variant is 10) +// see function NewV7 and NewV7FromReader +func makeV7(uuid []byte) { + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | ver | rand_a (12 bit seq) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |var| rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + _ = uuid[15] // bounds check + + t, s := getV7Time() + + uuid[0] = byte(t >> 40) + uuid[1] = byte(t >> 32) + uuid[2] = byte(t >> 24) + uuid[3] = byte(t >> 16) + uuid[4] = byte(t >> 8) + uuid[5] = byte(t) + + uuid[6] = 0x70 | (0x0F & byte(s>>8)) + uuid[7] = byte(s) +} + +// lastV7time is the last time we returned stored as: +// +// 52 bits of time in milliseconds since epoch +// 12 bits of (fractional nanoseconds) >> 8 +var lastV7time int64 + +const nanoPerMilli = 1000000 + +// getV7Time returns the time in milliseconds and nanoseconds / 256. +// The returned (milli << 12 + seq) is guarenteed to be greater than +// (milli << 12 + seq) returned by any previous call to getV7Time. +func getV7Time() (milli, seq int64) { + timeMu.Lock() + defer timeMu.Unlock() + + nano := timeNow().UnixNano() + milli = nano / nanoPerMilli + // Sequence number is between 0 and 3906 (nanoPerMilli>>8) + seq = (nano - milli*nanoPerMilli) >> 8 + now := milli<<12 + seq + if now <= lastV7time { + now = lastV7time + 1 + milli = now >> 12 + seq = now & 0xfff + } + lastV7time = now + return milli, seq +} diff --git a/vendor/github.com/lithammer/shortuuid/v4/README.md b/vendor/github.com/lithammer/shortuuid/v4/README.md index c13f947..581e8bd 100644 --- a/vendor/github.com/lithammer/shortuuid/v4/README.md +++ b/vendor/github.com/lithammer/shortuuid/v4/README.md @@ -1,11 +1,11 @@ # shortuuid [![Build Status](https://github.com/lithammer/shortuuid/workflows/CI/badge.svg)](https://github.com/lithammer/shortuuid/actions) -[![Godoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/lithammer/shortuuid) +[![Godoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://pkg.go.dev/github.com/lithammer/shortuuid/v4) A Go library that generates concise, unambiguous, URL-safe UUIDs. Based on and compatible with the Python library -[`shortuuid`](https://github.com/stochastic-technologies/shortuuid). +[`shortuuid`](https://github.com/skorokithakis/shortuuid). Often, one needs to use non-sequential IDs in places where users will see them, but the IDs must be as concise and easy to use as possible. shortuuid solves @@ -26,7 +26,8 @@ import ( ) func main() { - u := shortuuid.New() // KwSysDpxcBU9FNhGkn2dCf + u := shortuuid.New() + fmt.Println(u) // KwSysDpxcBU9FNhGkn2dCf } ``` @@ -37,8 +38,9 @@ instead of `New()`. shortuuid.NewWithNamespace("http://example.com") ``` -It's possible to use a custom alphabet as well, though it has to be 57 -characters long. +It's possible to use a custom alphabet as well (at least 2 +characters long). +It will automatically sort and remove duplicates from your alphabet to ensure consistency ```go alphabet := "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxy=" diff --git a/vendor/github.com/lithammer/shortuuid/v4/alphabet.go b/vendor/github.com/lithammer/shortuuid/v4/alphabet.go index 1e5356d..4ee3ef4 100644 --- a/vendor/github.com/lithammer/shortuuid/v4/alphabet.go +++ b/vendor/github.com/lithammer/shortuuid/v4/alphabet.go @@ -2,33 +2,44 @@ package shortuuid import ( "fmt" - "sort" - "strings" + "math" + "slices" ) // DefaultAlphabet is the default alphabet used. -const DefaultAlphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" +const ( + DefaultAlphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + rune1Max = 1<<7 - 1 +) type alphabet struct { - chars [57]rune - len int64 + chars []rune + len int64 + encLen int64 + singleBytes bool } -// Remove duplicates and sort it to ensure reproducability. +// Remove duplicates and sort it to ensure reproducibility. func newAlphabet(s string) alphabet { - abc := dedupe(strings.Split(s, "")) + abc := []rune(s) + slices.Sort(abc) + abc = slices.Compact(abc) - if len(abc) != 57 { - panic("encoding alphabet is not 57-bytes long") + if len(abc) < 2 { + panic("encoding alphabet must be at least two characters") } - sort.Strings(abc) a := alphabet{ - len: int64(len(abc)), + chars: abc, + len: int64(len(abc)), + encLen: int64(math.Ceil(128 / math.Log2(float64(len(abc))))), + singleBytes: true, } - - for i, char := range strings.Join(abc, "") { - a.chars[i] = char + for _, c := range a.chars { + if c > rune1Max { + a.singleBytes = false + break + } } return a @@ -41,25 +52,17 @@ func (a *alphabet) Length() int64 { // Index returns the index of the first instance of t in the alphabet, or an // error if t is not present. func (a *alphabet) Index(t rune) (int64, error) { - for i, char := range a.chars { - if char == t { - return int64(i), nil + i, j := 0, int(a.len) + for i < j { + h := int(uint(i+j) >> 1) + if a.chars[h] < t { + i = h + 1 + } else { + j = h } } - return 0, fmt.Errorf("element '%v' is not part of the alphabet", t) -} - -// dudupe removes duplicate characters from s. -func dedupe(s []string) []string { - var out []string - m := make(map[string]bool) - - for _, char := range s { - if _, ok := m[char]; !ok { - m[char] = true - out = append(out, char) - } + if i >= int(a.len) || a.chars[i] != t { + return 0, fmt.Errorf("element '%v' is not part of the alphabet", t) } - - return out + return int64(i), nil } diff --git a/vendor/github.com/lithammer/shortuuid/v4/base57.go b/vendor/github.com/lithammer/shortuuid/v4/base57.go deleted file mode 100644 index 2499600..0000000 --- a/vendor/github.com/lithammer/shortuuid/v4/base57.go +++ /dev/null @@ -1,91 +0,0 @@ -package shortuuid - -import ( - "fmt" - "math" - "math/big" - "strings" - - "github.com/google/uuid" -) - -type base57 struct { - // alphabet is the character set to construct the UUID from. - alphabet alphabet -} - -// Encode encodes uuid.UUID into a string using the most significant bits (MSB) -// first according to the alphabet. -func (b base57) Encode(u uuid.UUID) string { - var num big.Int - num.SetString(strings.Replace(u.String(), "-", "", 4), 16) - - // Calculate encoded length. - length := math.Ceil(math.Log(math.Pow(2, 128)) / math.Log(float64(b.alphabet.Length()))) - - return b.numToString(&num, int(length)) -} - -// Decode decodes a string according to the alphabet into a uuid.UUID. If s is -// too short, its most significant bits (MSB) will be padded with 0 (zero). -func (b base57) Decode(u string) (uuid.UUID, error) { - str, err := b.stringToNum(u) - if err != nil { - return uuid.Nil, err - } - return uuid.Parse(str) -} - -// numToString converts a number a string using the given alphabet. -func (b *base57) numToString(number *big.Int, padToLen int) string { - var ( - out []rune - digit *big.Int - ) - - alphaLen := big.NewInt(b.alphabet.Length()) - - zero := new(big.Int) - for number.Cmp(zero) > 0 { - number, digit = new(big.Int).DivMod(number, alphaLen, new(big.Int)) - out = append(out, b.alphabet.chars[digit.Int64()]) - } - - if padToLen > 0 { - remainder := math.Max(float64(padToLen-len(out)), 0) - out = append(out, []rune(strings.Repeat(string(b.alphabet.chars[0]), int(remainder)))...) - } - - reverse(out) - - return string(out) -} - -// stringToNum converts a string a number using the given alphabet. -func (b *base57) stringToNum(s string) (string, error) { - n := big.NewInt(0) - - for _, char := range s { - n.Mul(n, big.NewInt(b.alphabet.Length())) - - index, err := b.alphabet.Index(char) - if err != nil { - return "", err - } - - n.Add(n, big.NewInt(index)) - } - - if n.BitLen() > 128 { - return "", fmt.Errorf("number is out of range (need a 128-bit value)") - } - - return fmt.Sprintf("%032x", n), nil -} - -// reverse reverses a inline. -func reverse(a []rune) { - for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 { - a[i], a[j] = a[j], a[i] - } -} diff --git a/vendor/github.com/lithammer/shortuuid/v4/encoder.go b/vendor/github.com/lithammer/shortuuid/v4/encoder.go new file mode 100644 index 0000000..6990c29 --- /dev/null +++ b/vendor/github.com/lithammer/shortuuid/v4/encoder.go @@ -0,0 +1,158 @@ +package shortuuid + +import ( + "encoding/binary" + "fmt" + "github.com/google/uuid" + "math" + "math/bits" + "strings" +) + +type encoder struct { + // alphabet is the character set to construct the UUID from. + alphabet alphabet +} + +const ( + defaultBase = 57 + defaultEncLen = 22 + defaultNDigits = 10 + defaultDivisor = 362033331456891249 // 57^10 +) + +func maxPow(b uint64) (d uint64, n int) { + d, n = b, 1 + for m := math.MaxUint64 / b; d <= m; { + d *= b + n++ + } + return +} + +// Encode encodes uuid.UUID into a string using the most significant bits (MSB) +// first according to the alphabet. +func (e encoder) Encode(u uuid.UUID) string { + if e.alphabet.singleBytes { + return e.encodeSingleBytes(u) + } + return e.encode(u) +} + +func (e encoder) encodeSingleBytes(u uuid.UUID) string { + num := uint128{ + binary.BigEndian.Uint64(u[8:]), + binary.BigEndian.Uint64(u[:8]), + } + var r uint64 + var i int + var buf []byte + if e.alphabet.len == defaultBase { // compiler optimizations using constants for default base + buf = make([]byte, defaultEncLen) + for i = defaultEncLen - 1; num.Hi > 0 || num.Lo > 0; { + num, r = num.quoRem64(defaultDivisor) + for j := 0; j < defaultNDigits && i >= 0; j++ { + buf[i] = byte(e.alphabet.chars[r%defaultBase]) + r /= defaultBase + i-- + } + } + } else { + buf = make([]byte, e.alphabet.encLen) + l := uint64(e.alphabet.len) + d, n := maxPow(l) + for i = int(e.alphabet.encLen - 1); num.Hi > 0 || num.Lo > 0; { + num, r = num.quoRem64(d) + for j := 0; j < n && i >= 0; j++ { + buf[i] = byte(e.alphabet.chars[r%l]) + r /= l + i-- + } + } + } + for ; i >= 0; i-- { + buf[i] = byte(e.alphabet.chars[0]) + } + return string(buf[:]) +} + +func (e encoder) encode(u uuid.UUID) string { + num := uint128{ + binary.BigEndian.Uint64(u[8:]), + binary.BigEndian.Uint64(u[:8]), + } + var r uint64 + var outIndexes []uint64 + if e.alphabet.len == defaultBase { // compiler optimizations using constants for default base + outIndexes = make([]uint64, defaultEncLen) // avoids escaping to heap for base57 when used with constant + for i := defaultEncLen - 1; num.Hi > 0 || num.Lo > 0; { + num, r = num.quoRem64(defaultDivisor) + for j := 0; j < defaultNDigits && i >= 0; j++ { + outIndexes[i] = r % defaultBase + r /= defaultBase + i-- + } + } + } else { + outIndexes = make([]uint64, e.alphabet.encLen) + l := uint64(e.alphabet.len) + d, n := maxPow(l) + for i := int(e.alphabet.encLen - 1); num.Hi > 0 || num.Lo > 0; { + num, r = num.quoRem64(d) + for j := 0; j < n && i >= 0; j++ { + outIndexes[i] = r % l + r /= l + i-- + } + } + } + + var sb strings.Builder + sb.Grow(int(e.alphabet.encLen)) + for i := 0; i < int(e.alphabet.encLen); i++ { + sb.WriteRune(e.alphabet.chars[outIndexes[i]]) + } + return sb.String() +} + +// Decode decodes a string according to the alphabet into a uuid.UUID. If s is +// too short, its most significant bits (MSB) will be padded with 0 (zero). +func (e encoder) Decode(s string) (u uuid.UUID, err error) { + var n uint128 + var index int64 + + for _, char := range s { + index, err = e.alphabet.Index(char) + if err != nil { + return + } + n, err = n.mulAdd64(uint64(e.alphabet.len), uint64(index)) + if err != nil { + return + } + } + binary.BigEndian.PutUint64(u[:8], n.Hi) + binary.BigEndian.PutUint64(u[8:], n.Lo) + return +} + +type uint128 struct { + Lo, Hi uint64 +} + +func (u uint128) quoRem64(v uint64) (q uint128, r uint64) { + q.Hi, r = bits.Div64(0, u.Hi, v) + q.Lo, r = bits.Div64(r, u.Lo, v) + return +} + +func (u uint128) mulAdd64(m uint64, a uint64) (uint128, error) { + hi, lo := bits.Mul64(u.Lo, m) + p0, p1 := bits.Mul64(u.Hi, m) + lo, c0 := bits.Add64(lo, a, 0) + hi, c1 := bits.Add64(hi, p1, c0) + if p0 != 0 || c1 != 0 { + return uint128{}, fmt.Errorf("number is out of range (need a 128-bit value)") + } + return uint128{lo, hi}, nil +} diff --git a/vendor/github.com/lithammer/shortuuid/v4/shortuuid.go b/vendor/github.com/lithammer/shortuuid/v4/shortuuid.go index 7ae1ef5..0c51b9a 100644 --- a/vendor/github.com/lithammer/shortuuid/v4/shortuuid.go +++ b/vendor/github.com/lithammer/shortuuid/v4/shortuuid.go @@ -8,7 +8,7 @@ import ( // DefaultEncoder is the default encoder uses when generating new UUIDs, and is // based on Base57. -var DefaultEncoder = &base57{newAlphabet(DefaultAlphabet)} +var DefaultEncoder = &encoder{newAlphabet(DefaultAlphabet)} // Encoder is an interface for encoding/decoding UUIDs to strings. type Encoder interface { @@ -33,9 +33,9 @@ func NewWithNamespace(name string) string { switch { case name == "": u = uuid.New() - case strings.HasPrefix(strings.ToLower(name), "http://"): + case hasPrefixCaseInsensitive(name, "https://"): u = uuid.NewSHA1(uuid.NameSpaceURL, []byte(name)) - case strings.HasPrefix(strings.ToLower(name), "https://"): + case hasPrefixCaseInsensitive(name, "http://"): u = uuid.NewSHA1(uuid.NameSpaceURL, []byte(name)) default: u = uuid.NewSHA1(uuid.NameSpaceDNS, []byte(name)) @@ -47,6 +47,10 @@ func NewWithNamespace(name string) string { // NewWithAlphabet returns a new UUIDv4, encoded with base57 using the // alternative alphabet abc. func NewWithAlphabet(abc string) string { - enc := base57{newAlphabet(abc)} + enc := encoder{newAlphabet(abc)} return enc.Encode(uuid.New()) } + +func hasPrefixCaseInsensitive(s, prefix string) bool { + return len(s) >= len(prefix) && strings.EqualFold(s[:len(prefix)], prefix) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 33055bb..e18baa9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -32,14 +32,14 @@ github.com/go-pkgz/lgr github.com/go-pkgz/rest github.com/go-pkgz/rest/logger github.com/go-pkgz/rest/realip -# github.com/google/uuid v1.3.0 +# github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid # github.com/jessevdk/go-flags v1.6.1 ## explicit; go 1.20 github.com/jessevdk/go-flags -# github.com/lithammer/shortuuid/v4 v4.0.0 -## explicit; go 1.13 +# github.com/lithammer/shortuuid/v4 v4.2.0 +## explicit; go 1.21 github.com/lithammer/shortuuid/v4 # github.com/pmezard/go-difflib v1.0.0 ## explicit