在Go语言中生成一个随机的、固定长度的字节数组

iszxjhcz  于 2023-09-28  发布在  Go
关注(0)|答案(4)|浏览(101)

我有一个字节数组,固定长度为4。

token := make([]byte, 4)

我需要将每个字节设置为随机字节。我怎么能这样做,在最有效的问题?math/rand方法不提供随机字节函数,就我而言。
也许有一种内置的方法,或者我应该生成一个随机字符串并将其转换为字节数组?

qvsjd97n

qvsjd97n1#

Package rand

import "math/rand"

func读取

func Read(p []byte) (n int, err error)

Read从默认的Source中生成len(p)个随机字节,并将它们写入p。它总是返回len(p)和一个nil错误。
func(* 兰德)读取

func (r *Rand) Read(p []byte) (n int, err error)

Read生成len(p)随机字节并将它们写入p。它总是返回len(p)和一个nil错误。
比如说,

package main

import (
    "math/rand"
    "fmt"
)

func main() {
    token := make([]byte, 4)
    rand.Read(token)
    fmt.Println(token)
}

输出量:

[187 163 35 30]
czfnxgou

czfnxgou2#

Go 1.6在math/rand包中添加了一个新函数:

func Read(p []byte) (n int, err error)

其用随机数据填充所传递的byte片。使用rand.Read()

token := make([]byte, 4)
if _, err := rand.Read(token); err != nil {
    // Handle err
}
fmt.Println(token)

rand.Read()有两个返回值:“读取”字节数和(可选)error。这是为了符合一般的io.Reader接口,但是rand.Read()的文档声明(尽管它有签名)它实际上永远不会返回非nil错误,所以我们可以省略检查它,这将它简化为:

token := make([]byte, 4)
rand.Read(token)
fmt.Println(token)

在使用math/rand包之前,不要忘记调用rand.Seed()来正确初始化它,例如:

rand.Seed(time.Now().UnixNano())

注意:在Go 1.6之前没有math/rand.Read()函数,但是有(现在仍然是)crypto/rand.Read()函数,但是crypto/rand包实现了加密安全的伪随机数生成器,所以它比math/rand慢得多。

euoag5mw

euoag5mw3#

使用math.兰德意味着您正在使用操作系统提供的系统CSPRNG。这意味着使用/dev/urandom/和Windows的CryptGenRandom API。值得庆幸的是,Go的crypto/兰德包将这些实现细节抽象出来,以最大限度地降低出错的风险。

import(
   "crypto/rand"
   "encoding/base64"
 )

// GenerateRandomBytes returns securely generated random bytes. 
// It will return an error if the system's secure random
// number generator fails to function correctly, in which
// case the caller should not continue.
func GenerateRandomBytes(n int) ([]byte, error) {
     b := make([]byte, n)
    _, err := rand.Read(b)
    // Note that err == nil only if we read len(b) bytes.
    if err != nil {
       return nil, err
   }

   return b, nil
}
xv8emn3q

xv8emn3q4#

对于较新版本的go,math/rand被认为是不推荐使用的,应该使用crypto/rand。引用自It's Doc:rand.Read is deprecated: For almost all use cases, crypto/rand.Read is more appropriate

package main

import (
    "crypto/rand"
    "fmt"
)

func main() {
    token := make([]byte, 4)
    rand.Read(token)
    fmt.Println(token)
}

相关问题