-
Notifications
You must be signed in to change notification settings - Fork 7
/
Bits.go
85 lines (73 loc) · 1.56 KB
/
Bits.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package zksync
import "github.com/pkg/errors"
type Bits struct {
bits []bool
}
func NewBits(len uint) *Bits {
return &Bits{bits: make([]bool, len)}
}
func (b *Bits) Len() uint {
return uint(len(b.bits))
}
func (b *Bits) SetBit(i uint, v bool) {
// len is not checked, can cause panic
b.bits[i] = v
}
func (b *Bits) GetBit(i uint) bool {
// len is not checked, can cause panic
return b.bits[i]
}
func (b *Bits) Clone() *Bits {
clone := NewBits(b.Len())
copy(clone.bits, b.bits)
return clone
}
func (b *Bits) Append(a *Bits) *Bits {
b.bits = append(b.bits, a.bits...)
return b
}
func (b *Bits) Reverse() *Bits {
for i, j := 0, len(b.bits)-1; i < j; i, j = i+1, j-1 {
b.bits[i], b.bits[j] = b.bits[j], b.bits[i]
}
return b
}
func (b *Bits) String() (s string) {
for _, v := range b.bits {
if v {
s += `1`
} else {
s += `0`
}
}
return
}
func (b *Bits) ToBytesBE() ([]byte, error) {
bits := len(b.bits)
if bits%8 != 0 {
return nil, errors.New("Wrong number of bits to pack")
}
bytes := len(b.bits) / 8
res := make([]byte, bytes)
for i, b := range b.bits {
if b {
byteIdx := i / 8
bitIdx := 7 - i%8
res[byteIdx] = res[byteIdx] | 1<<bitIdx
}
}
return res, nil
}
func (b *Bits) FromBytesBE(bytes []byte) *Bits {
for i, v := range bytes {
b.SetBit(uint(i*8+0), v&0x80 > 0)
b.SetBit(uint(i*8+1), v&0x40 > 0)
b.SetBit(uint(i*8+2), v&0x20 > 0)
b.SetBit(uint(i*8+3), v&0x10 > 0)
b.SetBit(uint(i*8+4), v&0x08 > 0)
b.SetBit(uint(i*8+5), v&0x04 > 0)
b.SetBit(uint(i*8+6), v&0x02 > 0)
b.SetBit(uint(i*8+7), v&0x01 > 0)
}
return b
}