英文:
Generating a random, fixed-length byte array in Go
问题
我有一个长度为4的字节数组。
token := make([]byte, 4)
我需要将每个字节设置为一个随机字节。在效率最高的情况下,我该如何做到这一点?据我所知,math/rand
方法没有提供随机字节函数。
也许有一种内置的方法,或者我应该生成一个随机字符串然后将其转换为字节数组?
英文:
I have a byte array, with a fixed length of 4.
token := make([]byte, 4)
I need to set each byte to a random byte. How can I do so, in the most efficient matter? The math/rand
methods do not provide a Random Byte function, as far as I am concerned.
Perhaps there is a built-in way, or should I go with generating a random string and converting it to a byte array?
答案1
得分: 66
> rand 包
>
> import "math/rand"
>
> func Read
>
> func Read(p []byte) (n int, err error)
>
> Read 从默认的 Source 生成 len(p) 个随机字节,并将它们写入 p。它总是返回 len(p) 和一个空的错误。
>
> func (*Rand) Read
>
> func (r *Rand) Read(p []byte) (n int, err error)
>
> Read 从 r 生成 len(p) 个随机字节,并将它们写入 p。它总是返回 len(p) 和一个空的错误。
例如,
package main
import (
"math/rand";
"fmt";
)
func main() {
token := make([]byte, 4)
rand.Read(token)
fmt.Println(token)
}
输出:
[187 163 35 30]
英文:
> Package rand
>
> import "math/rand"
>
> func Read
>
> 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 (*Rand) Read
>
> 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.
For example,
package main
import (
"math/rand"
"fmt"
)
func main() {
token := make([]byte, 4)
rand.Read(token)
fmt.Println(token)
}
Output:
[187 163 35 30]
答案2
得分: 18
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 {
// 处理错误
}
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
要慢得多。
英文:
Go 1.6 added a new function to the math/rand
package:
func Read(p []byte) (n int, err error)
which fills the passed byte
slice with random data. Using this rand.Read()
:
token := make([]byte, 4)
if _, err := rand.Read(token); err != nil {
// Handle err
}
fmt.Println(token)
rand.Read()
has 2 return values: the number of "read" bytes and an (optional) error
. This is to conform with the general io.Reader
interface, but the documentation of rand.Read()
states that (despite its signature) it will never actually return a non-nil
error, so we may omit checking it, which simplifies it to this:
token := make([]byte, 4)
rand.Read(token)
fmt.Println(token)
Don't forget to call rand.Seed()
to properly initialize it before you use the math/rand
package, e.g.:
rand.Seed(time.Now().UnixNano())
Note: Prior to Go 1.6 there was no math/rand.Read()
function, but there was (and still is) a crypto/rand.Read()
function, but the crypto/rand
package implements a cryptographically secure pseudorandom number generator, so it is much slower than math/rand
.
答案3
得分: 16
使用math.Rand意味着您正在使用操作系统提供的系统CSPRNG。这意味着使用/dev/urandom和Windows的CryptGenRandom API。
幸运的是,Go的crypto/rand包将这些实现细节抽象化,以最小化出错的风险。
import (
"crypto/rand"
"encoding/base64"
)
// GenerateRandomBytes返回安全生成的随机字节。
// 如果系统的安全随机数生成器无法正常工作,它将返回错误,
// 在这种情况下,调用者不应继续执行。
func GenerateRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
// 注意,只有当我们读取了len(b)字节时,err == nil。
if err != nil {
return nil, err
}
return b, nil
}
英文:
Using math.Rand means that you are using the system CSPRNG that your operating system provides. This means using /dev/urandom/ and Windows’ CryptGenRandom API.
Go’s crypto/rand package, thankfully, abstracts these implementation details away to minimise the risk of getting it wrong.
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论