package random import ( "encoding/binary" "math/rand" ) const ( N = 312 M = 156 MATRIX_A = 0xB5026F5AA96619E9 UPPER_MASK = 0xFFFFFFFF80000000 LOWER_MASK = 0x7FFFFFFF ) type source struct { array [312]uint64 // state vector index uint64 // array index } func NewRand() *rand.Rand { return rand.New(NewSource64()) } func NewRand64() *rand.Rand { return rand.New(NewSource64()) } func NewSource() rand.Source { return &source{index: N + 1} } func NewSource64() rand.Source64 { return &source{index: N + 1} } func (s *source) Seed(seed int64) { s.array[0] = uint64(seed) for s.index = 1; s.index < N; s.index++ { s.array[s.index] = 0x5851F42D4C957F2D*(s.array[s.index-1]^(s.array[s.index-1]>>62)) + s.index } } func (s *source) Int63() int64 { return int64(s.Uint64() & 0x7FFFFFFFFFFFFFFE) } func (s *source) Uint64() uint64 { var i int var x uint64 magic := []uint64{0, MATRIX_A} if s.index >= N { if s.index == N+1 { s.Seed(int64(5489)) } for i = 0; i < N-M; i++ { x = (s.array[i] & UPPER_MASK) | (s.array[i+1] & LOWER_MASK) s.array[i] = s.array[i+(M)] ^ (x >> 1) ^ magic[int(x&uint64(1))] } for ; i < N-1; i++ { x = (s.array[i] & UPPER_MASK) | (s.array[i+1] & LOWER_MASK) s.array[i] = s.array[i+(M-N)] ^ (x >> 1) ^ magic[int(x&uint64(1))] } x = (s.array[N-1] & UPPER_MASK) | (s.array[0] & LOWER_MASK) s.array[N-1] = s.array[M-1] ^ (x >> 1) ^ magic[int(x&uint64(1))] s.index = 0 } x = s.array[s.index] s.index++ x ^= (x >> 29) & 0x5555555555555555 x ^= (x << 17) & 0x71D67FFFEDA60000 x ^= (x << 37) & 0xFFF7EEE000000000 x ^= x >> 43 return x } type KeyBlock struct { seed uint64 data [4096]byte } func NewKeyBlock(seed uint64, useMagicSeed bool) *KeyBlock { b := &KeyBlock{seed: seed} r := NewRand() r.Seed(int64(b.seed)) if useMagicSeed { // 2.8.0版本后加入的黑魔法 刘慈欣:6 r.Seed(int64(r.Uint64())) r.Uint64() } for i := 0; i < 4096>>3; i++ { binary.BigEndian.PutUint64(b.data[i<<3:], r.Uint64()) } return b } func (b *KeyBlock) Seed() uint64 { return b.seed } func (b *KeyBlock) XorKey() [4096]byte { return b.data }