tags:

views:

137

answers:

4

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.

+4  A: 

There 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.

Mark Byers
Damn you're just seconds faster then me :-)
Petriborg
why are you doing `int` conversion?
SilentGhost
SilentGhost: because he might be using Python 2.x and he might want the result as an int, not a long. It's not necessary, but it's not going to hurt either. You're welcome to omit the int conversion if you wish.
Mark Byers
Silent Ghost: I have now posted both versions. :)
Mark Byers
+1  A: 

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.

Alexander Gessler
A: 

Like this:

union splitme
{
   unsigned long in;
   unsigned char out[4];
}

Compilers tend to optimize this away to nearly nothing.

SF.
that doesn't look like python
SilentGhost
+5  A: 

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.

Alex Martelli
+1 Didn't know about that.
Mark Byers