今天项目里面遇到一个问题,一个业务需要动态生成多个随机数和随机字符串,都知道golang中生成随机数的核心是设置随机数种子,于是我先使用如下代码随机生成十个5位的字母,每一次循环都获取当前时间作为随机数种子来保证随机性。
func Test1(t *testing.T) {
for i := 0; i < 10; i++ {
//设置随机数种子
rand.Seed(time.Now().Unix())
bytes := make([]byte, 5)
for i := 0; i < 5; i++ {
b := rand.Intn(26) + 65
bytes[i] = byte(b)
}
fmt.Println(string(bytes))
}
}
=== RUN Test1
WCYBU
WCYBU
WCYBU
WCYBU
WCYBU
WCYBU
WCYBU
WCYBU
WCYBU
WCYBU
--- PASS: Test1 (0.00s)
PASS
可以看见结果是十条相同的数据,经过我测试发现是因为time.Now().Unix()
这个获取当前纳秒数函数在for循环的执行中每一次都是一样的,这个问题有点奇怪,我后面继续测试了生成100、1000、10000、20000次循环获取纳秒数,只有在20000次循环是才产生了两个不一样的纳秒数,所以这种方案设置随机数并不可取。于是我换了一种方案,直接以循环变量来作为随机种子,这样就可以完全保持种子的唯一。
func Test1(t *testing.T) {
for i := 0; i < 10; i++ {
rand.Seed(int64(i))
bytes := make([]byte, 5)
for i := 0; i < 5; i++ {
b := rand.Intn(26) + 65
bytes[i] = byte(b)
}
fmt.Println(string(bytes))
}
}
=== RUN Test1
CUBYH
XVLBZ
IMMOA
MTUOP
NOFDH
QMZSX
QFWAG
GOVHG
AGZGU
ZSKNP
--- PASS: Test1 (0.00s)
PASS
这样就保证了生成完全不同的随机字母