-
Notifications
You must be signed in to change notification settings - Fork 26
/
bitn.py
202 lines (174 loc) · 4.89 KB
/
bitn.py
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
"""
The bitn.BitBin and bitn.NBin classes
"""
import sys
class BitBin:
"""
bitn.Bitbin takes a byte string and
converts it to a integer, a very large integer
if needed. A 1500 bit integer is no problem.
several methods are available for slicing off bits.
"""
def __init__(self, bites):
# self.bites = bites
self.bitsize = self.idx = len(bites) << 3
self.bits = int.from_bytes(bites, byteorder="big")
def as_90k(self, num_bits):
"""
Returns num_bits
of bits as 90k time
"""
ninetyk = self.as_int(num_bits) / 90000.0
return round(ninetyk, 6)
def as_int(self, num_bits):
"""
Starting at self.idx of self.bits,
slice off num_bits of bits.
"""
if self.idx >= num_bits:
self.idx -= num_bits
return (self.bits >> (self.idx)) & ~(~0 << num_bits)
return self.negative_shift(num_bits)
def as_hex(self, num_bits):
"""
Returns the hex value
of num_bits of bits
"""
return hex(self.as_int(num_bits))
def as_ascii(self, num_bits):
"""
Returns num_bits of bits
as bytes decoded to as_ascii
"""
stuff = self.as_int(num_bits)
wide = num_bits >> 3
return int.to_bytes(stuff, wide, byteorder="big").decode(
"utf-8", errors="replace"
)
def as_charset(self, num_bits, charset):
"""
Returns num_bits of bits
as bytes decoded to as_ascii
"""
print(charset)
stuff = self.as_int(num_bits)
wide = num_bits >> 3
return int.to_bytes(stuff, wide, byteorder="big").decode(
charset, errors="replace"
)
def as_ticks(self, num_bits):
"""
Returns num_bits of bits
as bytes
"""
stuff = self.as_int(num_bits)
wide = num_bits >> 3
return int.to_bytes(stuff, wide, byteorder="big")
def as_flag(self, num_bits=1):
"""
Returns one bit as True or False
"""
return self.as_int(num_bits) & 1 == 1
def forward(self, num_bits):
"""
Advances the start point
forward by num_bits
"""
self.idx -= num_bits
def negative_shift(self, num_bits):
"""
negative_shift is called instead of
throwing a negative shift count error.
"""
print(
f"{num_bits} bits requested, but only {self.idx} bits left.",
file=sys.stderr,
)
print(
f"\n bytes remaining: {self.as_ticks(self.idx)} ",
file=sys.stderr,
)
class NBin:
"""
bitn.NBin is
the reverse BitBin.
Encodes data to integers
and then bytes
"""
def __init__(self):
self.nbits = 0
self.idx = 0
self.bites = b""
def nbits2bites(self):
"""
nbits2bites converts
the int self.nbits to bytes as self.bites
and sets self.nbits and self.idx to 0
"""
bites_wide = self.idx >> 3
self.bites += int.to_bytes(self.nbits, bites_wide, byteorder="big")
self.nbits = 0
self.idx = 0
def add_bites(self, plus_bites):
"""
add_bites appends plus_bites
to self.bites
"""
self.bites += plus_bites
# if self.idx % 8 == 0:
# self.nbits2bites()
def add_int(self, int_bits, bit_len):
"""
left shift nbits and append new_bits
"""
self.idx += bit_len
self.nbits = (self.nbits << bit_len) | int_bits
if self.idx % 8 == 0:
self.nbits2bites()
def add_90k(self, pts, bit_len=33):
"""
Converts 90k float timestamps
to an int and appends it to nbits
via self.add_int
"""
ninetyk = int(pts * 90000.0)
self.add_int(ninetyk, bit_len)
def add_hex(self, hex_str, bit_len):
"""
add_hex converts a
hex encoded string to an int
and appends it to self.nbits
via self.add_int
"""
dehexed = int(hex_str, 16)
self.add_int(dehexed, bit_len)
def add_flag(self, flg, bit_len=1):
"""
add_flag takes a boolean
value and adds it as an integer
to self.nbits via self.add_int
"""
bit_len = 1
self.add_int(flg.real, bit_len)
def reserve(self, num):
"""
reserve sets 'num' bits to 1
and appends them to self.nbits
via self.add_int
"""
bit_len = 1
while num:
self.add_int(1, bit_len)
num -= 1
def forward(self, num):
"""
Currently just an alias to reserve
"""
self.reserve(num)
def zeroed(self, num):
"""
zeroed sets num bits to zero
"""
bit_len = 1
while num:
self.add_int(0, bit_len)