github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/internal/rand/rand.go (about)

     1  package rand
     2  
     3  import (
     4  	crand "crypto/rand"
     5  	mrand "math/rand"
     6  
     7  	"sync"
     8  	"unsafe"
     9  )
    10  
    11  var src mrand.Source
    12  var lk sync.Mutex
    13  
    14  func Int63() (n int64) {
    15  	lk.Lock()
    16  	n = src.Int63()
    17  	lk.Unlock()
    18  	return
    19  }
    20  
    21  func Bytes(n int) (bs []byte) {
    22  	bs = make([]byte, n)
    23  
    24  	lk.Lock()
    25  
    26  	i := 0
    27  
    28  	var x int64
    29  	for j := 0; j < n/8; j++ {
    30  		x = src.Int63()
    31  
    32  		bs[i] = byte(x)
    33  		bs[i+1] = byte(x >> 8)
    34  		bs[i+2] = byte(x >> 16)
    35  		bs[i+3] = byte(x >> 24)
    36  		bs[i+4] = byte(x >> 32)
    37  		bs[i+5] = byte(x >> 40)
    38  		bs[i+6] = byte(x >> 48)
    39  		bs[i+7] = byte(x >> 56)
    40  
    41  		i += 8
    42  	}
    43  
    44  	if m := n % 8; m != 0 {
    45  		x = src.Int63()
    46  
    47  		for j := 0; j < m; j++ {
    48  			bs[i+j] = byte(x >> uint(8*j))
    49  		}
    50  	}
    51  
    52  	lk.Unlock()
    53  
    54  	return
    55  }
    56  
    57  func init() {
    58  	bs := make([]byte, 8)
    59  	_, err := crand.Read(bs)
    60  	if err != nil {
    61  		panic(err)
    62  	}
    63  
    64  	src = mrand.NewSource(*(*int64)(unsafe.Pointer(&bs[0])))
    65  }