github.com/scottcagno/storage@v1.8.0/pkg/util/rand.go (about) 1 package util 2 3 import ( 4 "bytes" 5 "math/rand" 6 "strings" 7 "time" 8 ) 9 10 var src = rand.NewSource(time.Now().UnixNano()) 11 12 const ( 13 letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 14 letterIdxBits = 6 // 6 bits to represent a letter index 15 letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits 16 letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits 17 ) 18 19 func RandString(n int) string { 20 sb := strings.Builder{} 21 sb.Grow(n) 22 // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! 23 for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { 24 if remain == 0 { 25 cache, remain = src.Int63(), letterIdxMax 26 } 27 if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 28 sb.WriteByte(letterBytes[idx]) 29 i-- 30 } 31 cache >>= letterIdxBits 32 remain-- 33 } 34 return sb.String() 35 } 36 37 func RandBytes(n int) []byte { 38 bb := bytes.Buffer{} 39 bb.Grow(n) 40 // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! 41 for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { 42 if remain == 0 { 43 cache, remain = src.Int63(), letterIdxMax 44 } 45 if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 46 bb.WriteByte(letterBytes[idx]) 47 i-- 48 } 49 cache >>= letterIdxBits 50 remain-- 51 } 52 return bb.Bytes() 53 } 54 55 func RandIntn(min, max int) int { 56 return rand.Intn(max-min) + min 57 } 58 59 func FormattedWidthString(s string, n int) string { 60 if len(s) == 0 { 61 return "" 62 } 63 if n >= len(s) { 64 return s 65 } 66 lines := make([]string, 0, (len(s)-1)/n+1) 67 j, k := 0, 0 68 for i := range s { 69 if j == n { 70 lines = append(lines, s[k:i]) 71 j, k = 0, i 72 } 73 j++ 74 } 75 lines = append(lines, s[k:]) 76 return strings.Join(lines, "\n") 77 } 78 79 func FormattedWidthBytes(b []byte, n int) []byte { 80 return []byte(FormattedWidthString(string(b), n)) 81 }