Chore: Generate shorter UIDs (#79843)

This commit is contained in:
Ryan McKinley 2024-01-24 11:27:46 -08:00 committed by GitHub
parent a81d3b1d22
commit c9ff6a9ab9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 15 deletions

View File

@ -8,6 +8,7 @@ import (
"sync"
"time"
"github.com/bwmarrin/snowflake"
"github.com/google/uuid"
)
@ -42,24 +43,39 @@ func IsShortUIDTooLong(uid string) bool {
return len(uid) > MaxUIDLength
}
var node *snowflake.Node
// GenerateShortUID will generate a UUID that can also be a k8s name
// it is guaranteed to have a character as the first letter
// This UID will be a valid k8s name
func GenerateShortUID() string {
mtx.Lock()
defer mtx.Unlock()
uid, err := uuid.NewRandom()
if err != nil {
// This should never happen... but this seems better than a panic
for i := range uid {
uid[i] = byte(uidrand.Intn(255))
if node == nil {
// ignoring the error happens when input outside 0-1023
node, _ = snowflake.NewNode(rand.Int63n(1024))
}
// Use UUIDs if snowflake failed (should be never)
if node == nil {
uid, err := uuid.NewRandom()
if err != nil {
// This should never happen... but this seems better than a panic
for i := range uid {
uid[i] = byte(uidrand.Intn(255))
}
}
uuid := uid.String()
if rune(uuid[0]) < rune('a') {
uuid = string(hexLetters[uidrand.Intn(len(hexLetters))]) + uuid[1:]
}
return uuid
}
uuid := uid.String()
if rune(uuid[0]) < rune('a') {
return string(hexLetters[uidrand.Intn(len(hexLetters))]) + uuid[1:]
}
return uuid
return string(hexLetters[uidrand.Intn(len(hexLetters))]) + // start with a letter
node.Generate().Base36() +
string(hexLetters[uidrand.Intn(len(hexLetters))]) // a bit more entropy
}
// ValidateUID checks the format and length of the string and returns error if it does not pass the condition

View File

@ -1,12 +1,13 @@
package util
import (
"fmt"
"sync"
"testing"
"cuelang.org/go/pkg/strings"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/teris-io/shortid"
"k8s.io/apimachinery/pkg/util/validation"
)
@ -48,14 +49,27 @@ func TestRandomUIDs(t *testing.T) {
t.Fatalf("created invalid name: %v", validation)
}
_, err := uuid.Parse(v)
require.NoError(t, err)
//fmt.Println(v)
// fmt.Println(v)
}
// t.FailNow()
}
func TestCaseInsensitiveCollisionsUIDs(t *testing.T) {
history := make(map[string]bool, 0)
for i := 0; i < 100000; i++ {
v := GenerateShortUID()
if false {
v, _ = shortid.Generate() // collides in less then 500 iterations
}
lower := strings.ToLower(v)
_, exists := history[lower]
require.False(t, exists, fmt.Sprintf("already found: %s (index:%d)", v, i))
history[lower] = true
}
}
func TestIsShortUIDTooLong(t *testing.T) {
var tests = []struct {
name string