github.com/rudderlabs/rudder-go-kit@v0.30.0/testhelper/rand/rand.go (about) 1 package rand 2 3 import ( 4 "math/rand" 5 "sync" 6 "time" 7 "unsafe" 8 ) 9 10 const ( 11 letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 12 letterIdxBits = 6 // 6 bits to represent a letter index 13 letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits 14 letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits 15 ) 16 17 var ( 18 src = rand.NewSource(time.Now().UnixNano()) 19 uniqueRandomStrings = make(map[string]struct{}) 20 uniqueRandomStringsMu sync.Mutex 21 ) 22 23 // String returns a random string 24 // Credits to https://stackoverflow.com/a/31832326/828366 25 func String(n int) string { 26 b := make([]byte, n) 27 // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! 28 for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { 29 if remain == 0 { 30 cache, remain = src.Int63(), letterIdxMax 31 } 32 if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 33 b[i] = letterBytes[idx] 34 i-- 35 } 36 cache >>= letterIdxBits 37 remain-- 38 } 39 40 return *(*string)(unsafe.Pointer(&b)) // skipcq: GSC-G103 41 } 42 43 // UniqueString returns a random string that is unique 44 func UniqueString(n int) string { 45 str := String(n) 46 47 uniqueRandomStringsMu.Lock() 48 defer uniqueRandomStringsMu.Unlock() 49 50 for { 51 if _, ok := uniqueRandomStrings[str]; !ok { 52 uniqueRandomStrings[str] = struct{}{} 53 return str 54 } 55 str = String(n) 56 } 57 }