gpt4 book ai didi

random - 使用 crypto/rand 通过 rand.Perm 生成排列

转载 作者:IT王子 更新时间:2023-10-29 01:09:23 25 4
gpt4 key购买 nike

Go 有两个随机数包:

  • crypto/rand,它提供了一种获取随机字节的方法
  • math/rand,它有一个很好的洗牌算法

我想使用 math/rand 中的 Perm 算法,但要为其提供高质量的随机数。

因为两个 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)
}

此代码有效。理想情况下,我不想自己定义 cryptoSource 类型,而只是将两个 rand 包放在一起,以便它们一起工作。那么在某处是否有此 cryptoSource 类型的预定义版本?

最佳答案

这基本上就是您需要做的。对于 math/rand 的常见用法,您通常不需要加密安全的随机源,因此没有提供适配器。通过直接在值中分配缓冲区空间,而不是在每次调用时都分配一个新 slice ,您可以使实现稍微高效一些。然而,在读取操作系统随机源失败的不太可能发生的情况下,这将需要 panic 以防止返回无效结果。

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

关于random - 使用 crypto/rand 通过 rand.Perm 生成排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40965044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com