Go: Cryptographically secure random numbers
Go has two packages for random numbers:
-
math/rand
implements a large selection of pseudo-random number generators. -
crypto/rand
implements a cryptographically secure pseudo-random number generator with a limited interface.
The two packages can be combined by calling rand.New
in package math/rand
with a source that gets its data from crypto/rand
.
import (
crand "crypto/rand"
rand "math/rand"
"encoding/binary"
"fmt"
"log"
)
func main() {
var src cryptoSource
rnd := rand.New(src)
fmt.Println(rnd.Intn(1000)) // a random number from 0 to 999
}
type cryptoSource struct{}
func (s cryptoSource) Seed(seed int64) {}
func (s cryptoSource) Int63() int64 {
return int64(s.Uint64() & ^uint64(1<<63))
}
func (s cryptoSource) Uint64() (v uint64) {
err := binary.Read(crand.Reader, binary.BigEndian, &v)
if err != nil {
log.Fatal(err)
}
return v
}
The crand.Reader
returns an error if the underlying system call fails. For instance if the runtime can't read /dev/urandom
on a *nix system or if CryptAcquireContext
fails on a Windows system.
Comments
Be the first to comment!