12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package core
- import (
- "math/big"
- "math/rand"
- cryptorand "crypto/rand"
- )
- func Rand(h RuntimeHandle, k func(*rand.Rand)(Object)) Observable {
- return Observable(func(pub DataPublisher) {
- randWorker <- func() {
- var r = rand.New(randSource { h })
- pub.AsyncReturn(k(r))
- }
- })
- }
- func RandBigInt(supremum *big.Int, h RuntimeHandle) Observable {
- if supremum.Sign() <= 0 {
- Crash(h, InvalidArgument, "non-positive random supremum")
- }
- return Observable(func(pub DataPublisher) {
- randWorker <- func() {
- pub.AsyncReturn(ObjIntFromBigInt(randBigInt(supremum, h)))
- }
- })
- }
- var randWorker = make(chan func(), 256)
- var _ = (func() struct{} {
- go (func() {
- for k := range randWorker {
- k()
- }
- })()
- return struct{}{}
- })()
- type randSource struct {
- h RuntimeHandle
- }
- func (src randSource) Seed(_ int64) {
- panic("dummy method")
- }
- func (src randSource) Int63() int64 {
- var n big.Int
- return randBigInt(n.Lsh(big.NewInt(1), 63), src.h).Int64()
- }
- func (src randSource) Uint64() uint64 {
- var n big.Int
- return randBigInt(n.Lsh(big.NewInt(1), 64), src.h).Uint64()
- }
- func randBigInt(supremum *big.Int, h RuntimeHandle) *big.Int {
- if supremum.Sign() <= 0 {
- panic("invalid argument")
- }
- var n, err = cryptorand.Int(cryptorand.Reader, supremum)
- if err != nil {
- Crash(h, FailedToGenerateRandomNumber, err.Error())
- }
- return n
- }
|