github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/x/stringsx/util.go (about) 1 package stringsx 2 3 import ( 4 "math/rand" 5 "time" 6 ) 7 8 var ( 9 visibleChars []byte 10 visibleCharsLen int 11 12 src = rand.NewSource(time.Now().UnixNano()) 13 ) 14 15 var GenRandomVisibleString = GenRandomVisibleStringV2 16 17 const ( 18 letterIdxBits = 7 // 7 bits to represent a letter index 19 letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits 20 letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits 21 ) 22 23 func init() { 24 visibleCharsLen = 95 // all visible chars [32,126] 95=1011111b 25 visibleChars = make([]byte, visibleCharsLen) 26 for i := byte(0); int(i) < visibleCharsLen; i++ { 27 visibleChars[i] = i + 32 28 } 29 } 30 31 func GenRandomVisibleStringV1(length int, excluded ...byte) string { 32 if length == 0 { 33 return "" 34 } 35 result := make([]byte, 0, length) 36 rand.Seed(time.Now().UnixNano() + int64(rand.Intn(100))) 37 for i := 0; i < length; { 38 SKIP: 39 idx := rand.Intn(visibleCharsLen) 40 c := visibleChars[idx] 41 if len(excluded) > 0 { 42 for _, v := range excluded { 43 if v == c { 44 goto SKIP 45 } 46 } 47 } 48 result = append(result, c) 49 i++ 50 } 51 return string(result) 52 } 53 54 func GenRandomVisibleStringV2(n int, excluded ...byte) string { 55 if n == 0 { 56 return "" 57 } 58 b := make([]byte, n) 59 // A src.Int63() generates 63 random bits, enough for letterIdxMax characters 60 for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { 61 if remain == 0 { 62 cache, remain = src.Int63(), letterIdxMax 63 } 64 if idx := int(cache & letterIdxMask); idx < len(visibleChars) { 65 c := visibleChars[idx] 66 if len(excluded) > 0 { 67 for _, v := range excluded { 68 if v == c { 69 goto SKIP 70 } 71 } 72 } 73 b[i] = c 74 i-- 75 } 76 SKIP: 77 cache >>= letterIdxBits 78 remain-- 79 } 80 return string(b) 81 }