2011-05-30 154 views
28

我试图在Go中生成随机数(整数),但无济于事。我发现crypto/rand中的rand包,这似乎是我想要的,但我无法从文档中告诉如何使用它。这就是我想现在:在Go中生成随机数

b := []byte{} 
    something, err := rand.Read(b) 
    fmt.Printf("something = %v\n", something) 
    fmt.Printf("err = %v\n", err) 

但不幸的是这总是输出:

something = 0 
    err = <nil> 

有没有办法解决这个问题,以便它实际上产生的随机数?另外,有没有办法设置这个随机数的上限呢?

+0

我预计日常填补阵列'B'用随机字节,但是你问了很多。 – sarnold 2011-05-30 22:33:04

+0

我也是 - 我只是新手,并不熟悉调用约定等。 – 2011-05-31 00:18:44

+1

它会填充'b',但是'b'是一个空片(并且支持数组的大小为0)。所以rand.Read()没有空间来存储任何东西,并且在你的'something'变量中返回0,表示没有存储任何内容。 'b:= make([] byte,4)'会更合适,允许rand.Read在b – nos 2011-06-06 12:01:44

回答

24

crypto/rand提供的随机数据只是二进制流,但你可以从它使用encoding/binary阅读整数:

package main 

import "encoding/binary" 
import "crypto/rand" 

func main() { 
    var n int32 
    binary.Read(rand.Reader, binary.LittleEndian, &n) 
    println(n) 
} 
+0

中存储4个字节好,这对我很有用。谢谢! – 2011-05-30 23:16:02

+0

你应该检查binary.Read错误吗? – Gabriel 2015-07-14 20:00:47

+0

我在操场上试过这个,总是得到相同的结果:https://play.golang.org/p/Bh-f4QEyKf – Karlom 2017-09-17 18:16:27

27

根据您的使用情况下,另一种选择是math/rand包。如果您生成的数字需要完全不可预知,请不要这样做。如果您需要获得可重现的结果,这可能会有所帮助 - 只需传入您首次通过的同一颗种子即可。

这里是典型的“种子与当前时间发电机并产生了许多”计划:

package main 

import (
    "fmt" 
    "math/rand" 
    "time" 
) 

func main() { 
    rand.Seed(time.Now().Unix()) 
    fmt.Println(rand.Int()) 
} 
16

随着2012年4月1日的,的郎的稳定版本发布之后,你可以做以下:

 
package main

import "fmt" import "time" import "math/rand"

func main() { rand.Seed(time.Now().UnixNano()) // takes the current time in nanoseconds as the seed fmt.Println(rand.Intn(100)) // this gives you an int up to but not including 100 }

+0

这几乎是我在询问伪随机数时所期望的。 'time.Now()。Unix()'并不像'UnixNano()'那样足够。 – AndrewPK 2015-01-09 18:08:36