Skip to content

Instantly share code, notes, and snippets.

@jinroh
Last active January 22, 2018 07:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jinroh/7ec9e44db1e5f796ede6920f75862477 to your computer and use it in GitHub Desktop.
Save jinroh/7ec9e44db1e5f796ede6920f75862477 to your computer and use it in GitHub Desktop.
Generate random string in Go
BenchmarkRandomStringA-4 2000000 702 ns/op
BenchmarkRandomStringB-4 10000000 120 ns/op
BenchmarkRandomStringC-4 20000000 115 ns/op
BenchmarkRandomStringD-4 10000000 121 ns/op
func RandomStringA(n int) string {
const letters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
b := make([]byte, n)
lenLetters := len(letters)
for i := 0; i < n; i++ {
b[i] = letters[rand.Intn(lenLetters)]
}
return string(b)
}
func RandomStringB(rng *rand.Rand, n int) string {
const letters = `0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-`
b := make([]byte, ((n+9)/10)*10)
for i := 0; i < n; i += 10 {
rn := rng.Uint64()
b[i+0] = letters[(rn&0x0FC0000000000000)>>54]
b[i+1] = letters[(rn&0x003F000000000000)>>48]
b[i+2] = letters[(rn&0x0000FC0000000000)>>42]
b[i+3] = letters[(rn&0x000003F000000000)>>36]
b[i+4] = letters[(rn&0x0000000FC0000000)>>30]
b[i+5] = letters[(rn&0x000000003F000000)>>24]
b[i+6] = letters[(rn&0x0000000000FC0000)>>18]
b[i+7] = letters[(rn&0x000000000003F000)>>12]
b[i+8] = letters[(rn&0x0000000000000FC0)>>6]
b[i+9] = letters[(rn&0x000000000000003F)>>0]
}
return string(b[:n])
}
func RandomStringC(rng *rand.Rand, n int) string {
// extract 10 letters — 60 bits of entropy — for each pseudo-random uint64
const K = 10
const L = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
b := make([]byte, ((n+K-1)/K)*K)
for i := 0; i < n; i += K {
rn := rng.Uint64()
for j := 0; j < K; j++ {
b[i+j] = L[rn&0x3F]
rn >>= 6
}
}
return string(b[:n])
}
func RandomStringD(rng *rand.Rand, n int) string {
const letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, rng.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = rng.Int63(), letterIdxMax
}
idx := int(cache & letterIdxMask)
b[i] = letterBytes[idx]
i--
cache >>= letterIdxBits
remain--
}
return string(b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment