Golang随机数发生器如何正确播种
我试图在Go中生成一个随机string,这里是我迄今为止写的代码:
package main import ( "bytes" "fmt" "math/rand" "time" ) func main() { fmt.Println(randomString(10)) } func randomString(l int) string { var result bytes.Buffer var temp string for i := 0; i < l; { if string(randInt(65, 90)) != temp { temp = string(randInt(65, 90)) result.WriteString(temp) i++ } } return result.String() } func randInt(min int, max int) int { rand.Seed(time.Now().UTC().UnixNano()) return min + rand.Intn(max-min) }
我的实施非常缓慢。 使用time
播种会在同一time
带来相同的随机数,所以循环一次又一次地迭代。 我如何改进我的代码?
每次你设置相同的种子,你会得到相同的序列。 所以当然如果你把种子设置成快速的循环,你可能会多次用相同的种子来调用它。
在你的情况下,当你调用你的randInt
函数,直到你有一个不同的值,你等待的时间(由纳米返回)改变。
至于所有的伪随机库 ,你只能设置一次种子,例如当初始化你的程序,除非你特别需要重现一个给定的序列(通常是为了debugging)。
之后,您只需调用Intn
即可获取下一个随机整数。
将rand.Seed( time.Now().UTC().UnixNano())
行从randInt函数移动到main的开始处,一切都会更快。
还要注意,我认为你可以简化你的string构build:
package main import ( "fmt" "math/rand" "time" ) func main() { rand.Seed(time.Now().UTC().UnixNano()) fmt.Println(randomString(10)) } func randomString(l int) string { bytes := make([]byte, l) for i := 0; i < l; i++ { bytes[i] = byte(randInt(65, 90)) } return string(bytes) } func randInt(min int, max int) int { return min + rand.Intn(max-min) }
只是为了抛弃后人:有时使用初始字符集string生成一个随机string是更可取的。 如果string应该由人工手动input,这很有用; 不包括0,O,1和l可以帮助减less用户错误。
var alpha = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789" // generates a random string of fixed size func srand(size int) string { buf := make([]byte, size) for i := 0; i < size; i++ { buf[i] = alpha[rand.Intn(len(alpha))] } return string(buf) }
我通常在init()
块内设置种子。 他们logging在这里: http : //golang.org/doc/effective_go.html#init
好吧为什么这么复杂!
package main import ( "fmt" "math/rand" "time" ) func main() { rand.Seed( time.Now().UnixNano()) var bytes int for i:= 0 ; i < 10 ; i++{ bytes = rand.Intn(6)+1 fmt.Println(bytes) } //fmt.Println(time.Now().UnixNano()) }
这是基于dystroy的代码,但适合我的需要。
它是六死(rands ints 1 =< i =< 6
)
func randomInt (min int , max int ) int { var bytes int bytes = min + rand.Intn(max) return int(bytes) }
上面的function是完全一样的东西。
我希望这个信息是有用的。
这是纳秒,获得相同种子两次的机会是多less。
无论如何,感谢您的帮助,这里是我的最终解决scheme基于所有的input。
package main import ( "math/rand" "time" ) func init() { rand.Seed(time.Now().UTC().UnixNano()) } // generates a random string func srand(min, max int, readable bool) string { var length int var char string if min < max { length = min + rand.Intn(max-min) } else { length = min } if readable == false { char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" } else { char = "ABCDEFHJLMNQRTUVWXYZabcefghijkmnopqrtuvwxyz23479" } buf := make([]byte, length) for i := 0; i < length; i++ { buf[i] = char[rand.Intn(len(char)-1)] } return string(buf) } // For testing only func main() { println(srand(5, 5, true)) println(srand(5, 5, true)) println(srand(5, 5, true)) println(srand(5, 5, false)) println(srand(5, 7, true)) println(srand(5, 10, false)) println(srand(5, 50, true)) println(srand(5, 10, false)) println(srand(5, 50, true)) println(srand(5, 10, false)) println(srand(5, 50, true)) println(srand(5, 10, false)) println(srand(5, 50, true)) println(srand(5, 4, true)) println(srand(5, 400, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) println(srand(6, 5, true)) }