Generating a random, fixed-length byte array in Go

前端 未结 3 1262
没有蜡笔的小新
没有蜡笔的小新 2021-02-05 03:43

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

相关标签:
3条回答
  • 2021-02-05 03:53

    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
    }
    
    0 讨论(0)
  • 2021-02-05 04:04

    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]
    
    0 讨论(0)
  • 2021-02-05 04:07

    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.

    0 讨论(0)
提交回复
热议问题