Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: unsigned 32 bit bitwise arithmetic

Tags:

python

math

Trying to answer to another post whose solution deals with IP addresses and netmasks, I got stuck with plain bitwise arithmetic.

Is there a standard way, in Python, to carry on bitwise AND, OR, XOR, NOT operations assuming that the inputs are "32 bit" (maybe negative) integers or longs, and that the result must be a long in the range [0, 2**32]?

In other words, I need a working Python counterpart to the C bitwise operations between unsigned longs.

EDIT: the specific issue is this:

>>> m = 0xFFFFFF00   # netmask 255.255.255.0 >>> ~m -4294967041L         # wtf?! I want 255 
like image 263
Federico A. Ramponi Avatar asked Oct 16 '08 23:10

Federico A. Ramponi


People also ask

How do you represent a 32 bit integer in Python?

The int data type in python simply the same as the signed integer. A signed integer is a 32-bit integer in the range of -(2^31) = -2147483648 to (2^31) – 1=2147483647 which contains positive or negative numbers. It is represented in two's complement notation.

Can you Bitshift in Python?

The bitwise right shift operator in python shifts the bits of the binary representation of the input number to the right side by a specified number of places. The empty bits created by shifting the bits are filled by 0s. The syntax for the bitwise right shift is a >> n.

Is there an unsigned int in Python?

Python doesn't have builtin unsigned types. You can use mathematical operations to compute a new int representing the value you would get in C, but there is no "unsigned value" of a Python int. The Python int is an abstraction of an integer value, not a direct access to a fixed-byte-size integer.


2 Answers

You can use ctypes and its c_uint32:

>>> import ctypes >>> m = 0xFFFFFF00 >>> ctypes.c_uint32(~m).value 255L 

So what I did here was casting ~m to a C 32-bit unsigned integer and retrieving its value back in Python format.

like image 121
DzinX Avatar answered Sep 20 '22 00:09

DzinX


You can mask everything by 0xFFFFFFFF:

>>> m = 0xFFFFFF00 >>> allf = 0xFFFFFFFF >>> ~m & allf 255L 
like image 34
John Millikin Avatar answered Sep 19 '22 00:09

John Millikin