Python: unsigned 32 bit bitwise arithmetic
Question:
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
Answers:
from numpy import uint32
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.
You can mask everything by 0xFFFFFFFF
:
>>> m = 0xFFFFFF00
>>> allf = 0xFFFFFFFF
>>> ~m & allf
255L
This is a module that I created a long time ago, and it might be of help to you:
It provides at least a CIDR
class with subnet arithmetic. Check the test cases at the end of the module for examples.
You could also xor with 0xFFFFFFFF, which is equivalent to the “unsigned complement”.
>>> 0xFFFFFF00 ^ 0xFFFFFFFF
255
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
from numpy import uint32
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.
You can mask everything by 0xFFFFFFFF
:
>>> m = 0xFFFFFF00
>>> allf = 0xFFFFFFFF
>>> ~m & allf
255L
This is a module that I created a long time ago, and it might be of help to you:
It provides at least a CIDR
class with subnet arithmetic. Check the test cases at the end of the module for examples.
You could also xor with 0xFFFFFFFF, which is equivalent to the “unsigned complement”.
>>> 0xFFFFFF00 ^ 0xFFFFFFFF
255