package replaydetector import ( "fmt" ) // fixedBigInt is the fix-sized multi-word integer. type fixedBigInt struct { bits []uint64 n uint msbMask uint64 } // newFixedBigInt creates a new fix-sized multi-word int. func newFixedBigInt(n uint) *fixedBigInt { chunkSize := (n + 63) / 64 if chunkSize == 0 { chunkSize = 1 } return &fixedBigInt{ bits: make([]uint64, chunkSize), n: n, msbMask: (1 << (64 - n%64)) - 1, } } // Lsh is the left shift operation. func (s *fixedBigInt) Lsh(n uint) { if n == 0 { return } nChunk := int(n / 64) nN := n % 64 for i := len(s.bits) - 1; i >= 0; i-- { var carry uint64 if i-nChunk >= 0 { carry = s.bits[i-nChunk] << nN if i-nChunk-1 >= 0 { carry |= s.bits[i-nChunk-1] >> (64 - nN) } } s.bits[i] = (s.bits[i] << n) | carry } s.bits[len(s.bits)-1] &= s.msbMask } // Bit returns i-th bit of the fixedBigInt. func (s *fixedBigInt) Bit(i uint) uint { if i >= s.n { return 0 } chunk := i / 64 pos := i % 64 if s.bits[chunk]&(1<= s.n { return } chunk := i / 64 pos := i % 64 s.bits[chunk] |= 1 << pos } // String returns string representation of fixedBigInt. func (s *fixedBigInt) String() string { var out string for i := len(s.bits) - 1; i >= 0; i-- { out += fmt.Sprintf("%016X", s.bits[i]) } return out }