decred.org/dcrwallet/v3@v3.1.0/wallet/rand.go (about) 1 // Copyright (c) 2019-2021 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package wallet 6 7 import ( 8 "crypto/rand" 9 "sync" 10 11 "decred.org/dcrwallet/v3/internal/uniformprng" 12 ) 13 14 var prng *uniformprng.Source 15 var prngMu sync.Mutex 16 17 func init() { 18 var err error 19 prng, err = uniformprng.RandSource(rand.Reader) 20 if err != nil { 21 panic(err) 22 } 23 } 24 25 func randInt63n(n int64) int64 { 26 defer prngMu.Unlock() 27 prngMu.Lock() 28 return prng.Int63n(n) 29 } 30 31 func shuffle(n int, swap func(i, j int)) { 32 if n < 0 { 33 panic("shuffle: negative n") 34 } 35 if int64(n) >= 1<<32 { 36 panic("shuffle: large n") 37 } 38 39 defer prngMu.Unlock() 40 prngMu.Lock() 41 42 // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 43 for i := uint32(0); i < uint32(n); i++ { 44 j := prng.Uint32n(uint32(n)-i) + i 45 swap(int(i), int(j)) 46 } 47 }