如何正确播种随机数生成器 [英] How to properly seed random number generator

查看:137
本文介绍了如何正确播种随机数生成器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Go中生成一个随机字符串,这是我到目前为止编写的代码:

I am trying to generate a random string in Go and here is the code I have written so far:

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进行播种会在一定时间内带来相同的随机数,因此循环会一次又一次地迭代.如何改善我的代码?

My implementation is very slow. Seeding using time brings the same random number for a certain time, so the loop iterates again and again. How can I improve my code?

推荐答案

每次设置相同的种子,您将获得相同的序列.因此,当然,如果您将种子设置为快速循环中的时间,则可能会多次调用相同的种子.

Each time you set the same seed, you get the same sequence. So of course if you're setting the seed to the time in a fast loop, you'll probably call it with the same seed many times.

在您的情况下,当您调用randInt函数直到您拥有不同的值时,您正在等待时间(由Nano返回)更改.

In your case, as you're calling your randInt function until you have a different value, you're waiting for the time (as returned by Nano) to change.

对于所有伪随机库,您只需设置一次种子即可,除非您特别需要重现给定的序列(通常仅用于调试和单元测试),否则请在初始化程序时使用此示例.

As for all pseudo-random libraries, you have to set the seed only once, for example when initializing your program unless you specifically need to reproduce a given sequence (which is usually only done for debugging and unit testing).

之后,您只需调用Intn即可获得下一个随机整数.

After that you simply call Intn to get the next random integer.

rand.Seed(time.Now().UTC().UnixNano())行从randInt函数移至main的开头,一切都会更快.

Move the rand.Seed(time.Now().UTC().UnixNano()) line from the randInt function to the start of the main and everything will be faster.

还请注意,我认为您可以简化字符串的构建:

Note also that I think you can simplify your string building:

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)
}

这篇关于如何正确播种随机数生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆