在 Go 中生成一个随机的、固定长度的字节数组
Generating a random, fixed-length byte array in Go
我有一个字节数组,固定长度为4。
token := make([]byte, 4)
我需要将每个字节设置为随机字节。在最有效的情况下,我该怎么做?就我而言,math/rand
方法不提供随机字节功能。
也许有内置方法,或者我应该生成一个随机字符串并将其转换为字节数组?
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()
有 2 个 return 值:"read" 字节数和一个(可选)error
. This is to conform with the general io.Reader
接口,但是 rand.Read()
的文档说明那(尽管它的签名)它实际上永远不会 return 一个非 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()
function, but the crypto/rand
包实现了一个加密安全的伪随机数生成器,所以它比math/rand
.
import "math/rand"
func Read(p []byte) (n int, err error)
Read generates len(p) random bytes from the default Source and writes
them into p. It always returns len(p) and a nil error.
func (r *Rand) Read(p []byte) (n int, err error)
Read generates len(p) random bytes and writes them into p. It always
returns len(p) and a nil error.
例如,
package main
import (
"math/rand"
"fmt"
)
func main() {
token := make([]byte, 4)
rand.Read(token)
fmt.Println(token)
}
输出:
[187 163 35 30]
使用math.Rand表示您正在使用操作系统提供的系统CSPRNG。这意味着使用 /dev/urandom/ 和 Windows' CryptGenRandom API。
值得庆幸的是,Go 的 crypto/rand 包将这些实现细节抽象化,以最大限度地降低出错的风险。
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
}
我有一个字节数组,固定长度为4。
token := make([]byte, 4)
我需要将每个字节设置为随机字节。在最有效的情况下,我该怎么做?就我而言,math/rand
方法不提供随机字节功能。
也许有内置方法,或者我应该生成一个随机字符串并将其转换为字节数组?
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()
有 2 个 return 值:"read" 字节数和一个(可选)error
. This is to conform with the general io.Reader
接口,但是 rand.Read()
的文档说明那(尽管它的签名)它实际上永远不会 return 一个非 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()
function, but the crypto/rand
包实现了一个加密安全的伪随机数生成器,所以它比math/rand
.
import "math/rand"
func Read(p []byte) (n int, err error)
Read generates len(p) random bytes from the default Source and writes them into p. It always returns len(p) and a nil error.
func (r *Rand) Read(p []byte) (n int, err error)
Read generates len(p) random bytes and writes them into p. It always returns len(p) and a nil error.
例如,
package main
import (
"math/rand"
"fmt"
)
func main() {
token := make([]byte, 4)
rand.Read(token)
fmt.Println(token)
}
输出:
[187 163 35 30]
使用math.Rand表示您正在使用操作系统提供的系统CSPRNG。这意味着使用 /dev/urandom/ 和 Windows' CryptGenRandom API。 值得庆幸的是,Go 的 crypto/rand 包将这些实现细节抽象化,以最大限度地降低出错的风险。
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
}