Is there a quick way in python to split a 32-bit variable, say, a1a2a3a4 into a1, a2, a3, a4 quickly? I've done it by changing the value into hex and then splitting it, but it seems like a waste of time doing int->string->int.
views:
137answers:
4There isn't really such thing as a 32-bit variable in Python. Is this what you mean?
x = 0xa1a2a3a4
a4 = int(x & 0xff)
a3 = int((x >> 8) & 0xff)
a2 = int((x >> 16) & 0xff)
a1 = int(x >> 24)
As SilentGhost points out, you don't need the int conversion, so you can do this:
a4 = x & 0xff
a3 = (x >> 8) & 0xff
a2 = (x >> 16) & 0xff
a1 = x >> 24
Note that in older versions of Python, the second version will return longs if the value of x is greater than 0x7fffffff and ints otherwise. The first version always returns int. In newer versions of Python the two types are unified so you don't have to worry about this detail.
Use bitwise operations.
For example:
myvar = 0xcdf100cd
a0 = myvar&0xff
a1 = (myvar>>8)&0xff
a2 = (myvar>>16)&0xff
a3 = (myvar>>24)&0xff
the &0xff keeps the lower 8 bits of the value and zeros the rest, while the bitshift operator (>>) is used to shift the byte you extracting into these lower 8 bits.
Like this:
union splitme
{
unsigned long in;
unsigned char out[4];
}
Compilers tend to optimize this away to nearly nothing.
Standard library module struct does short work of it:
>>> import struct
>>> x = 0xa1a2a3a4
>>> struct.unpack('4B', struct.pack('>I', x))
(161, 162, 163, 164)
"packing" with format '>I' makes x into a 4-byte string in big-endian order, which can then immediately be "unpacked" into four unsigned byte-size values with format '4B'. Easy peasy.