forked from TrueCloudLab/frostfs-node
[#851] util/rand: use single random source
It is much more convenient to skip source creation. Also fix some bugs: 1. `cryptoSource.Int63()` now returns number in [0, 1<<63) as required by `rand.Source` interface. 2. Replace `cryptoSource.Uint63()` with `cryptoSource.Uint64` to allow generate uint64 numbers directly (see rand.Source64 docs). Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
c35cdb3684
commit
5828f43e52
8 changed files with 56 additions and 66 deletions
|
@ -6,41 +6,39 @@ import (
|
|||
mrand "math/rand"
|
||||
)
|
||||
|
||||
type cryptoSource struct{}
|
||||
|
||||
// Read is alias for crypto/rand.Read.
|
||||
var Read = crand.Read
|
||||
|
||||
// New constructs the source of random numbers.
|
||||
func New() *mrand.Rand {
|
||||
return mrand.New(&cryptoSource{})
|
||||
}
|
||||
|
||||
func (s *cryptoSource) Seed(int64) {}
|
||||
|
||||
func (s *cryptoSource) Int63() int64 {
|
||||
return int64(s.Uint63())
|
||||
}
|
||||
|
||||
func (s *cryptoSource) Uint63() uint64 {
|
||||
buf := make([]byte, 8)
|
||||
if _, err := crand.Read(buf); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return binary.BigEndian.Uint64(buf)
|
||||
}
|
||||
var source = mrand.New(&cryptoSource{})
|
||||
|
||||
// Uint64 returns a random uint64 value.
|
||||
func Uint64(r *mrand.Rand, max int64) uint64 {
|
||||
if max <= 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var i int64 = -1
|
||||
for i < 0 {
|
||||
i = r.Int63n(max)
|
||||
}
|
||||
|
||||
return uint64(i)
|
||||
func Uint64() uint64 {
|
||||
return source.Uint64()
|
||||
}
|
||||
|
||||
// Uint64 returns a random uint32 value.
|
||||
func Uint32() uint32 {
|
||||
return source.Uint32()
|
||||
}
|
||||
|
||||
// Shuffle randomizes the order of elements.
|
||||
// n is the number of elements. Shuffle panics if n < 0.
|
||||
// swap swaps the elements with indexes i and j.
|
||||
func Shuffle(n int, swap func(i, j int)) {
|
||||
source.Shuffle(n, swap)
|
||||
}
|
||||
|
||||
// cryptoSource is math/rand.Source which takes entropy via crypto/rand.
|
||||
type cryptoSource struct{}
|
||||
|
||||
// Seed implements math/rand.Source.
|
||||
func (s *cryptoSource) Seed(int64) {}
|
||||
|
||||
// Int63 implements math/rand.Source.
|
||||
func (s *cryptoSource) Int63() int64 {
|
||||
return int64(s.Uint64() >> 1)
|
||||
}
|
||||
|
||||
// Uint64 implements math/rand.Source64.
|
||||
func (s *cryptoSource) Uint64() uint64 {
|
||||
var buf [8]byte
|
||||
_, _ = crand.Read(buf[:]) // always returns nil
|
||||
return binary.BigEndian.Uint64(buf[:])
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue