github.com/chwjbn/xclash@v0.2.0/transport/ssr/tools/random.go (about)

     1  package tools
     2  
     3  import (
     4  	"encoding/binary"
     5  
     6  	"github.com/chwjbn/xclash/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  }