Reading a multi-byte number
Jeff Epler
jepler at unpythonic.net
Mon May 19 16:54:47 EDT 2003
> Quoth Batista, Facundo:
> > valor += ord(car) * (255 ^ exp)
>
On Mon, May 19, 2003 at 02:30:28PM -0600, Steven Taschuk wrote:
> (Btw, shouldn't that be "255**exp"?)
No, it should probably involve 256. (Or <<8)
Try the "struct" module. It will let you read multi-byte numbers, provided
that the length in bytes is 1, 2, 4 (or 8 on platforms with 'long long').
If you want to read different lengths, use of struct.unpack may still be
an advantage, because you could do up to 8 bytes at a time instead of 1.
Or it might be premature optimization. Something like the following
(untested):
import struct
def unpack(bytestring):
nbytes = len(bytestring)
num_quads = nbytes / 8
num_chars = nbytes % 8
print num_quads, num_chars
format = "<%dQ%dB" % (num_quads, num_chars)
parts = struct.unpack(format, bytestring)
v = 0l
shift = 0
for i in range(num_quads):
v = v | (parts[i] * 1L << shift)
shift = shift + 64
for i in range(num_chars):
v = v | (parts[num_quads + i] * 1L << shift)
shift = shift + 8
return v
Of course, if what you want is a way to write Python long numbers
relatively efficiently, you might want to use 'marshal' to do so. Consider
a 1000-bit number:
>>> len(str(1l<<1000))
302
>>> len(pickle.dumps(1l<<1000))
306
>>> len(marshal.dumps(1l<<1000))
139
>>> 1000/8
125
so the overhead of marshal is quite small for large numbers (1/16 length +
a few extra bytes) and this also encodes the length of the number.
Jeff
More information about the Python-list
mailing list