github.com/kelleygo/clashcore@v1.0.2/transport/ssr/tools/random.go (about) 1 package tools 2 3 import ( 4 "encoding/binary" 5 6 "github.com/kelleygo/clashcore/common/pool" 7 ) 8 9 // XorShift128Plus - a pseudorandom number generator 10 type XorShift128Plus struct { 11 s [2]uint64 12 } 13 14 func (r *XorShift128Plus) Next() uint64 { 15 x := r.s[0] 16 y := r.s[1] 17 r.s[0] = y 18 x ^= x << 23 19 x ^= y ^ (x >> 17) ^ (y >> 26) 20 r.s[1] = x 21 return x + y 22 } 23 24 func (r *XorShift128Plus) InitFromBin(bin []byte) { 25 var full []byte 26 if len(bin) < 16 { 27 full := pool.Get(16)[:0] 28 defer pool.Put(full) 29 full = append(full, bin...) 30 for len(full) < 16 { 31 full = append(full, 0) 32 } 33 } else { 34 full = bin 35 } 36 r.s[0] = binary.LittleEndian.Uint64(full[:8]) 37 r.s[1] = binary.LittleEndian.Uint64(full[8:16]) 38 } 39 40 func (r *XorShift128Plus) InitFromBinAndLength(bin []byte, length int) { 41 var full []byte 42 if len(bin) < 16 { 43 full := pool.Get(16)[:0] 44 defer pool.Put(full) 45 full = append(full, bin...) 46 for len(full) < 16 { 47 full = append(full, 0) 48 } 49 } 50 full = bin 51 binary.LittleEndian.PutUint16(full, uint16(length)) 52 r.s[0] = binary.LittleEndian.Uint64(full[:8]) 53 r.s[1] = binary.LittleEndian.Uint64(full[8:16]) 54 for i := 0; i < 4; i++ { 55 r.Next() 56 } 57 }