Go 有两个随机数包:
crypto/rand,它提供了一种获取随机字节的方法math/rand,它有一个很好的打乱整数的算法我想使用Perm中的算法math/rand,但为其提供高质量的随机数。
由于这两个rand包是同一标准库的一部分,因此应该有一种方法将它们组合起来,以便crypto/rand提供用于math/rand.Perm生成排列的良好随机数源。
这里(以及Playground上)是我编写的用于连接这两个包的代码:
package main
import (
cryptoRand "crypto/rand"
"encoding/binary"
"fmt"
mathRand "math/rand"
)
type cryptoSource struct{}
func (s cryptoSource) Int63() int64 {
bytes := make([]byte, 8, 8)
cryptoRand.Read(bytes)
return int64(binary.BigEndian.Uint64(bytes) >> 1)
}
func (s cryptoSource) Seed(seed int64) {
panic("seed")
}
func main() {
rnd := mathRand.New(&cryptoSource{})
perm := rnd.Perm(52)
fmt.Println(perm)
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效。理想情况下,我不想cryptoSource自己定义类型,而只是将两个rand包粘在一起,以便它们一起工作。那么是否有这种类型的预定义版本cryptoSource?
这基本上就是你需要做的。您并不经常需要加密安全的随机源来进行 的常见使用math/rand,因此没有提供适配器。通过直接在值中分配缓冲区空间,而不是在每次调用时分配一个新切片,可以使实现稍微更高效。然而,万一读取操作系统随机源失败,则需要恐慌以防止返回无效结果。
type cryptoSource [8]byte
func (s *cryptoSource) Int63() int64 {
_, err := cryptoRand.Read(s[:])
if err != nil {
panic(err)
}
return int64(binary.BigEndian.Uint64(s[:]) & (1<<63 - 1))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1128 次 |
| 最近记录: |