grokify/mogo

View on GitHub
crypto/randutil/seed.go

Summary

Maintainability
A
0 mins
Test Coverage
package randutil

import (
    "crypto/rand"
    "encoding/binary"
    "time"
)

// NewSeedInt64Crypto creates an `int64` seed value for `math/rand`.
// This is preferred over `NewSeedInt64Time()`.
// See: https://stackoverflow.com/a/54491783/1908967
func NewSeedInt64Crypto() (int64, error) {
    var b [8]byte
    _, err := rand.Read(b[:])
    if err != nil {
        return 0, err
    }
    return int64(binary.LittleEndian.Uint64(b[:])), nil
}

// NewSeedInt64Time creates an `int64` seed value for `math/rand` based on
// `time.Now()`. This can have reduced entropy if used constantly throughout
// with shourl time differentials.
// See: https://stackoverflow.com/a/12321192/1908967
func NewSeedInt64Time() int64 {
    return time.Now().UnixNano()
}

// CryptoRandSource is a `crypto/rand` backed source that satisfies
// the `math/rand.Source` interface definition. It can be used as
// `r := rand.New(NewCryptoRandSource())`
// See: https://stackoverflow.com/a/35208651/1908967
type CryptoRandSource struct{}

func NewCryptoRandSource() CryptoRandSource {
    return CryptoRandSource{}
}

func (CryptoRandSource) Int63() int64 {
    var b [8]byte
    _, err := rand.Read(b[:])
    if err != nil {
        panic(err) // `math/rand.Source` interface only returns `int64`
    }
    // mask off sign bit to ensure positive number
    return int64(binary.LittleEndian.Uint64(b[:]) & (1<<63 - 1))
}

func (CryptoRandSource) Seed(int64) {}