SHARE
TWEET

Untitled

a guest Jul 21st, 2019 51 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package bits
  2.  
  3. import (
  4.     "fmt"
  5.     "strings"
  6. )
  7.  
  8. const (
  9.     blen    = 8
  10.     Invalid = -1
  11. )
  12.  
  13. type Bits struct {
  14.     buf []byte
  15. }
  16.  
  17. func New(buf []byte) (*Bits, error) {
  18.     if len(buf) == 0 {
  19.         return nil, fmt.Errorf("can not create a Bits from an empty buffer")
  20.     }
  21.     return &Bits{buf}, nil
  22. }
  23.  
  24. func (b Bits) Len() int {
  25.     return len(b.buf) * blen
  26. }
  27.  
  28. func (b Bits) String() string {
  29.     parts := make([]string, len(b.buf))
  30.     for i, v := range b.buf {
  31.         parts[i] = fmt.Sprintf("%0*b", blen, v)
  32.     }
  33.     return strings.Join(parts, "")
  34. }
  35.  
  36. func (b *Bits) RotateLeft(c int) error {
  37.     if c <= 0 {
  38.         return fmt.Errorf("can not rotate with c <= 0")
  39.     }
  40.     return nil
  41. }
  42.  
  43. func (b *Bits) RotateRight(c int) error {
  44.     if c <= 0 {
  45.         return fmt.Errorf("can not rotate with c <= 0")
  46.     }
  47.     return nil
  48. }
  49.  
  50. func (b Bits) GetBit(pos int) (int64, error) {
  51.     if pos < 0 || pos > b.Len() {
  52.         return Invalid, fmt.Errorf("invalid position %d", pos)
  53.     } else {
  54.         ix, off := pos/blen, pos%blen
  55.         val := int64(b.buf[ix]) & (128 >> uint(off))
  56.         return val >> uint(blen-off-1), nil
  57.     }
  58. }
  59.  
  60. func (b Bits) GetBits(pos, length int, swap bool) (int64, error) {
  61.     if pos < 0 || pos-length > b.Len() {
  62.         return Invalid, fmt.Errorf("invalid position %d", pos)
  63.     }
  64.     switch length {
  65.     case 0:
  66.         return Invalid, fmt.Errorf("length must be greater than 0")
  67.     case 1:
  68.         return b.GetBit(pos)
  69.     default:
  70.         var sum int64
  71.  
  72.         s := pos / blen
  73.         e := s + ((length + (length % blen)) / blen)
  74.         d := length - blen
  75.         buf := b.buf[s:e]
  76.  
  77.         if swap {
  78.             mid, mod := len(buf)/2, len(buf)%2
  79.             if mod%2 != 0 {
  80.                 return Invalid, fmt.Errorf("can not swap")
  81.             }
  82.             tmp := make([]byte, len(buf), len(buf))
  83.             for _, b := range buf {
  84.                 tmp[mid] = b
  85.                 mid++
  86.                 if mid >= len(buf) {
  87.                     mid = 0
  88.                 }
  89.             }
  90.             buf = tmp
  91.         }
  92.  
  93.         for i, v := range buf {
  94.             m := int64((1 << uint(d)) - 1)
  95.             d = length - d
  96.  
  97.             sum += (int64(v) & m) << uint(8*(len(buf)-i-1))
  98.         }
  99.         return sum, nil
  100.     }
  101. }
  102.  
  103. //Uint returns a big endian integer from Bits.
  104. func (b Bits) Uint(pos, length int) int64 {
  105.     if v, err := b.GetBits(pos, length, false); err != nil {
  106.         return Invalid
  107.     } else {
  108.         return v
  109.     }
  110. }
  111.  
  112. //UintLe returns an unsigned little endian integer from Bits.
  113. func (b Bits) UintLe(pos, length int) int64 {
  114.     if v, err := b.GetBits(pos, length, true); err != nil {
  115.         return Invalid
  116.     } else {
  117.         return v
  118.     }
  119. }
  120.  
  121. //Int returns a big endian Integer from Bits.
  122. func (b Bits) Int(pos, length int) int64 {
  123.     if v, err := b.GetBits(pos, length, false); err != nil {
  124.         return Invalid
  125.     } else {
  126.         if b.IsSet(pos) {
  127.             v = (1<<uint(length) - 1) + ^v
  128.         }
  129.         return v
  130.     }
  131. }
  132.  
  133. //IntLe returns a little endian integer from Bits.
  134. func (b Bits) IntLe(pos, length int) int64 {
  135.     if v, err := b.GetBits(pos, length, true); err != nil {
  136.         return Invalid
  137.     } else {
  138.         if b.IsSet(pos) {
  139.             v = (1<<uint(length) - 1) + ^v
  140.         }
  141.         return v
  142.     }
  143. }
  144.  
  145. func (b Bits) IsSet(pos int) bool {
  146.     if v, err := b.GetBit(pos); err != nil {
  147.         return false
  148.     } else {
  149.         return v == 1
  150.     }
  151. }
  152.  
  153. func (b Bits) AreSets(pos ...int) bool {
  154.     for _, p := range pos {
  155.         if !b.IsSet(p) {
  156.             return false
  157.         }
  158.     }
  159.     return true
  160. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top