为什么每次重新启动程序时math / rand都会返回相同的结果?

时间:2014-09-21 16:37:51

标签: string random go

我有点困惑。我有一个随机字符串生成器,这里是代码:

package utils

import (
  "fmt"
  "math/rand"
)

var chars = []rune("abcdefghijklmnopqrstuvwxyz0123456789")

func RandSeq(n int) string {
  b := make([]rune, n)
  for i := range b {
    b[i] = chars[rand.Intn(len(chars))]
  }
  fmt.Println(string(b))
  return string(b)
}

每次运行时,它都会生成一个新的随机字符串,但是如果我重新启动服务器,结果会重复。以下是一些结果:

go run main.go
fpllngzieyoh43e0133ols6k1hh2gdny
xxvi7hvszwk1b182tvjzjpezi4hx9gvm
kir0xcta0opsb5qipjzb3h3x9kcegta5
m1zcv5drxckn42gb50anxndsckjdwgfw
5japz01zicapy9eqixuc9uehq235v48c
51wgg1gypq4s9miwn1dxkjqd614m58f0
fyy29g6ujmxbouxshy2plmkmhlnmdbfh
f7kq8u26873eql4yyp7fyilbb72nrtlc

go run main.go
fpllngzieyoh43e0133ols6k1hh2gdny
xxvi7hvszwk1b182tvjzjpezi4hx9gvm
kir0xcta0opsb5qipjzb3h3x9kcegta5
m1zcv5drxckn42gb50anxndsckjdwgfw
5japz01zicapy9eqixuc9uehq235v48c

知道为什么会这样吗?

2 个答案:

答案 0 :(得分:7)

在生成任意随机数之前,您需要Seed随机数生成器。值得使用的是当前的unix时间戳:

import (
    "math/rand"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
}

请注意,您应该只在启动时(或分叉后)播种一次RNG,而不是在每个随机数生成之前播种。

答案 1 :(得分:2)

如果未设置rand.Seed,则会将种子默认为1,每次都会为您提供相同的随机数。

启动时使用rand等随机数播种rand.Seed(time.Now().UnixNano())会在每次运行程序时为您提供更改结果。

您还可以创建自己的随机变量,如:

var random = rand.New(rand.NewSource(time.Now().UnixNano()))

func main() {
    num := random.Intn(10)
    fmt.Println(num)
    num = random.Intn(10)
    fmt.Println(num)
}