github.com/yaling888/clash@v1.53.0/transport/ssr/tools/random.go (about) 1 package tools 2 3 import ( 4 "encoding/binary" 5 6 "github.com/yaling888/clash/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 bufP := pool.GetBufferWriter() 28 defer pool.PutBufferWriter(bufP) 29 30 *bufP = append(*bufP, bin...) 31 for len(*bufP) < 16 { 32 *bufP = append(*bufP, 0) 33 } 34 full = *bufP 35 } else { 36 full = bin 37 } 38 r.s[0] = binary.LittleEndian.Uint64(full[:8]) 39 r.s[1] = binary.LittleEndian.Uint64(full[8:16]) 40 } 41 42 func (r *XorShift128Plus) InitFromBinAndLength(bin []byte, length int) { 43 var full []byte 44 if len(bin) < 16 { 45 bufP := pool.GetBufferWriter() 46 defer pool.PutBufferWriter(bufP) 47 48 *bufP = append(*bufP, bin...) 49 for len(*bufP) < 16 { 50 *bufP = append(*bufP, 0) 51 } 52 full = *bufP 53 } else { 54 full = bin 55 } 56 binary.LittleEndian.PutUint16(full, uint16(length)) 57 r.s[0] = binary.LittleEndian.Uint64(full[:8]) 58 r.s[1] = binary.LittleEndian.Uint64(full[8:16]) 59 for i := 0; i < 4; i++ { 60 r.Next() 61 } 62 }