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?
import "math/Rand"
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.
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]
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
.
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
}