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  }