本文将详细的介绍Go语言中如何正确使用rand.Intn()函数作为核心,来生成指定长度的随机字符串。
既然是随机的,我们就需要用到随机函数。我们需要导入 math/rand 这个包。
import (
"time"
"math/rand"
)
我们需要使用 time.Now().UnixNano() 获取当前系统时间戳作为随机数的种子。
func init(){
rand.Seed(time.Now().UnixNano())
}
使用 rand.Seed() 设置初始数值。因为计算机生成的随机数实际上并不是真正的随机数,而是伪随机数;如果计算随机序列的初始数值相同,那么计算出的随机序列也会是相同的。所以我们要对随机数值设置,以确保程序每次运行时所产生的随机数不同。
这段代码放在 init() 函数中,init() 不需要调用,会自动在导入时运行或运行于 main() 函数前。
定义一个 rune 切片,当然,你也可以使用 byte 切片,占用更少的内存:
var letters = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
你也可以向其加入特殊字符。
实现函数如下:
func GetRandomString(l int) string { b := make([]rune, l) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) }
GetRandomString() 函数须传递一个 int 值,表明为随机数的长度,成功运行则返回 一个 string 类型的值。
首先创建一个临时的 rune 切片,用于存储要返回的值。
b := make([]rune, l)
通过 rand.Intn(n) 获取一个 0 – n 的随机数。n 不能<=0,否则将触发一个panic。这里我们的 n 就是 字符串种子的长度。
rand.Intn(len(letters))
从字符串种子里获得一个随机字符:
letters[rand.Intn(len(letters))]
遍历 b,将随机字符顺序的写入,最后使用 string 函数将 rune 切片转换成字符串返回。
完整源码:
package main
import (
"time"
"math/rand"
)
var letters = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
//GetRandomString ...
func GetRandomString(l int) string {
b := make([]rune, l)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func init(){
rand.Seed(time.Now().UnixNano())
}
其实上面这段代码是还有优化余地的,比如将 rune 切片换成 byte 切片,可以节省一些内存;然后是 len(letters) 完全可以运行在 for 块外面,而不是在 for 中被执行多次:
sl := len(letters)
for i := range b {
b[i] = letters[rand.Intn(sl)]
}
还有一点,该函数的复用性并不强,因为无法指定字符串种子。
func GetRandomString(l int) string{}
完全可以更改成这种形式:
func GetRandomString(l int,s [] rune) string{}