2008-10-16 35 views
27

Tratando de responder a otra publicación cuya solución se ocupa de las direcciones IP y las máscaras de red, me quedé atrapado con la aritmética bit a bit.Python: aritmética bit a bit sin signo de 32 bit

Hay una manera estándar, en Python, de llevar a cabo las operaciones Y, O, XOR, NOT a nivel de bits, suponiendo que las entradas son enteros o longitudes "32 bit" (quizás negativas) y que el resultado debe ser largo en el rango [0, 2 ** 32]?

En otras palabras, necesito una contraparte de Python que funcione con las operaciones de bit C entre longitudes sin firmar.

EDIT: la cuestión específica es la siguiente:

>>> m = 0xFFFFFF00 # netmask 255.255.255.0 
>>> ~m 
-4294967041L   # wtf?! I want 255 
+0

Imagino que la tipificación libre de Pythons sería jugar con cualquier algoritmo como este ... También quiero ver uno, solo por curiosidad. –

+0

A partir de Python 3.3, algunos usuarios que lo encuentren pueden estar interesados ​​en [el módulo ipaddress] (http://docs.python.org/dev/library/ipaddress). – gerrit

Respuesta

36

Puede enmascarar todo por 0xFFFFFFFF:

>>> m = 0xFFFFFF00 
>>> allf = 0xFFFFFFFF 
>>> ~m & allf 
255L 
+1

Esta estrategia también ayuda con [bash arithmetic] (http://stackoverflow.com/questions/3222379/how-to-efficientlyconvert-long-int-to-dotted-quad-ip-in-bash). – bstpierre

+1

Está realizando una operación más de la necesaria. ANDing a NOT es lo mismo que un XOR. Entonces, 'm^allf' es lo que necesitas. – HardlyKnowEm

+0

@mlefavor No sé de dónde sacó la idea de que '~ a & b' es lo mismo que' a^b'. No es en general. –

9
from numpy import uint32 
+0

No es portátil, pero funciona. +1 –

+2

¿Por qué no es portátil? – gerrit

+0

@gerrit ¿Se está refiriendo al hecho de que requiere que el sistema tenga instalado el módulo numpy mientras que ctypes es parte de core python? – penguin359

49

Puede utilizar ctypes y su c_uint32:

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

Entonces lo que hice aquí fue echando a un C 32- Un número entero sin signo y recuperando su valor en formato Python.

+1

Portátil, y funciona. +1 –

1

Este es un módulo que creé hace mucho tiempo, y que podría ser de ayuda para usted:

IPv4Utils

Proporciona al menos una clase CIDR con aritmética de subred. Verifique los casos de prueba al final del módulo para ver ejemplos.

0

También podría xor con 0xFFFFFFFF, que es equivalente al "complemento sin signo".

>>> 0xFFFFFF00^0xFFFFFFFF 
255