1
- from math import ceil
1
+ from math import ceil , floor
2
2
from io import BytesIO
3
3
from struct import pack , unpack
4
4
@@ -167,11 +167,9 @@ def read_var_list(stream, data_type):
167
167
168
168
# compressed integer
169
169
170
-
171
170
def int_to_c_int (n , base_bytes = 1 ):
172
171
"""
173
- Convert integer to compresed integer
174
-
172
+ Convert integer to compressed integer
175
173
:param n: integer.
176
174
:param base_bytes: len of bytes base from which start compression.
177
175
:return: bytes.
@@ -183,7 +181,15 @@ def int_to_c_int(n, base_bytes=1):
183
181
if l <= base_bytes * 8 :
184
182
return n .to_bytes (base_bytes , byteorder = "big" )
185
183
prefix = 0
186
- payload_bytes = ceil ((l )/ 8 ) - base_bytes + 1
184
+ payload_bytes = ceil ((l )/ 8 ) - base_bytes
185
+ a = payload_bytes
186
+ while True :
187
+ add_bytes = floor ((a ) / 8 )
188
+ a = add_bytes
189
+ if add_bytes >= 1 :
190
+ add_bytes += floor ((payload_bytes + add_bytes ) / 8 ) - floor ((payload_bytes ) / 8 )
191
+ payload_bytes += add_bytes
192
+ if a == 0 : break
187
193
extra_bytes = int (ceil ((l + payload_bytes )/ 8 ) - base_bytes )
188
194
for i in range (extra_bytes ):
189
195
prefix += 2 ** i
@@ -193,7 +199,31 @@ def int_to_c_int(n, base_bytes=1):
193
199
if prefix .bit_length () % 8 :
194
200
prefix = prefix << 8 - prefix .bit_length () % 8
195
201
n ^= prefix
196
- return n .to_bytes (ceil (n .bit_length ()/ 8 ), byteorder = "big" )
202
+ return n .to_bytes (ceil (n .bit_length () / 8 ), byteorder = "big" )
203
+
204
+
205
+ def c_int_len (n , base_bytes = 1 ):
206
+ """
207
+ Get length of compressed integer from integer value
208
+ :param n: bytes.
209
+ :param base_bytes: len of bytes base from which start compression.
210
+ :return: integer.
211
+ """
212
+ if n == 0 :
213
+ return base_bytes
214
+ l = n .bit_length () + 1
215
+ if l <= base_bytes * 8 :
216
+ return base_bytes
217
+ payload_bytes = ceil ((l ) / 8 ) - base_bytes
218
+ a = payload_bytes
219
+ while True :
220
+ add_bytes = floor ((a ) / 8 )
221
+ a = add_bytes
222
+ if add_bytes >= 1 :
223
+ add_bytes += floor ((payload_bytes + add_bytes ) / 8 ) - floor ((payload_bytes ) / 8 )
224
+ payload_bytes += add_bytes
225
+ if a == 0 : break
226
+ return int (ceil ((l + payload_bytes )/ 8 ))
197
227
198
228
199
229
def c_int_to_int (b , base_bytes = 1 ):
@@ -222,24 +252,6 @@ def c_int_to_int(b, base_bytes=1):
222
252
return n
223
253
224
254
225
- def c_int_len (n , base_bytes = 1 ):
226
- """
227
- Get length of compressed integer from integer value
228
-
229
- :param n: bytes.
230
- :param base_bytes: len of bytes base from which start compression.
231
- :return: integer.
232
- """
233
- if n == 0 :
234
- return base_bytes
235
- l = n .bit_length () + 1
236
- min_bits = base_bytes * 8 - 1
237
- if l <= min_bits + 1 :
238
- return base_bytes
239
- payload_bytes = ceil ((l )/ 8 ) - base_bytes + 1
240
- return int (ceil ((l + payload_bytes )/ 8 ))
241
-
242
-
243
255
# generic big endian MPI format
244
256
def bn_bytes (v , have_ext = False ):
245
257
ext = 0
0 commit comments