web-dev-qa-db-fra.com

Génération d'un tableau d'octets aléatoire de longueur fixe dans Go

J'ai un tableau d'octets, avec une longueur fixe de 4.

token := make([]byte, 4)

Je dois définir chaque octet sur un octet aléatoire. Comment puis-je le faire, de la manière la plus efficace? Le math/Rand les méthodes ne fournissent pas de fonction d'octet aléatoire, en ce qui me concerne.

Peut-être existe-t-il une méthode intégrée, ou devrais-je choisir de générer une chaîne aléatoire et de la convertir en un tableau d'octets?

16
Momo

Package Rand

import "math/Rand" 

lecture func

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

La lecture génère len (p) octets aléatoires à partir de la source par défaut et les écrit dans p. Il renvoie toujours len (p) et une erreur nulle.

f nc (* Rand) l

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

Read génère len (p) octets aléatoires et les écrit dans p. Il renvoie toujours len (p) et une erreur nulle.

Par exemple,

package main

import (
    "math/Rand"
    "fmt"
)

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

Production:

[187 163 35 30]
28
peterSO

Go 1.6 a ajouté une nouvelle fonction au package math/Rand :

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

qui remplit la tranche byte passée avec des données aléatoires. En utilisant ceci Rand.Read() :

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

Rand.Read() a 2 valeurs de retour: le nombre d'octets "lus" et un (facultatif) error . C'est pour se conformer à l'interface générale io.Reader , mais la documentation de Rand.Read() déclare que (malgré sa signature), il ne retournera jamais réellement un non -nil erreur, nous pouvons donc omettre de le vérifier, ce qui le simplifie:

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

N'oubliez pas d'appeler Rand.Seed() pour l'initialiser correctement avant d'utiliser le package math/Rand, Par exemple:

Rand.Seed(time.Now().UnixNano())

Remarque: Avant Go 1.6, il n'y avait pas de fonction math/Rand.Read(), mais il y avait (et il y a toujours) une fonction crypto/Rand.Read() , mais la crypto/Rand package implémente un générateur de nombres pseudo-aléatoires sécurisé cryptographiquement, il est donc beaucoup plus lent que math/Rand.

10
icza

L'utilisation de math.Rand signifie que vous utilisez le système CSPRNG fourni par votre système d'exploitation. Cela signifie utiliser/dev/urandom/et l'API CryptGenRandom de Windows. Le package crypto/Rand de Go, heureusement, résume ces détails d'implémentation pour minimiser le risque de se tromper.

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
GraphicalDot