| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- 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<<pos) != 0 {
- return 1
- }
- return 0
- }
- // SetBit sets i-th bit to 1.
- func (s *fixedBigInt) SetBit(i uint) {
- if i >= 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
- }
|