How to generate a random string in Go
Created
Modified
Using rand.Int63 Function
Int63 returns a non-negative pseudo-random 63-bit integer as an int64 from the default Source.
package main
import (
"fmt"
"math/rand"
"time"
)
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func RandStringByLenth(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letters[rand.Int63()%int64(len(letters))]
}
return string(b)
}
func main() {
// Don't forget
rand.Seed(time.Now().UTC().UnixNano())
for range "012345" {
s := RandStringByLenth(6)
fmt.Println(s)
}
}
GjwtZy wZotMg qRKVLB RDQtvQ RRbTrB gzMuMm
Don't forget about the rand.Seed(), otherwise you got the same string every first time launch.
Masking
We can maintain the equal distribution of letters by using only as many of the lowest bits of the random number as many is required to represent the number of letters. So here is the solution:
package main
import (
"fmt"
"math/rand"
"time"
)
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
letterIdxBits = 6
letterIdxMask = 1<<letterIdxBits - 1
letterIdxMax = 63 / letterIdxBits
)
func RandStringByLenth(n int) string {
b := make([]byte, n)
// A rand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, rand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = rand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letters) {
b[i] = letters[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
func main() {
// Don't forget
rand.Seed(time.Now().UTC().UnixNano())
for range "012345" {
s := RandStringByLenth(6)
fmt.Println(s)
}
}
SADUwS ufPPAG eNmPcJ JMFEtV NHkRrN gOlDuC
Using base64 Function
If you want cryptographically secure random numbers, and the exact charset is flexible (say, base64 is fine), you can calculate exactly what the length of random characters you need from the desired output size.
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
"math"
)
func RandStringByBase64(n int) string {
buff := make([]byte, int(math.Ceil(float64(n)/float64(1.33333333333))))
rand.Read(buff)
str := base64.RawURLEncoding.EncodeToString(buff)
return str[:n]
}
func main() {
for range "012345" {
s := RandStringByBase64(6)
fmt.Println(s)
}
}
QnPVHr mTA0nZ h4HPrV Yj7ZS2 TF8jo9 KKqM5_