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 }