En Python, ¿cuál es la mejor manera de determinar si una dirección IP (por ejemplo, '127.0.0.1'
o '10.98.76.6'
) está en un private network? El código no suena difícil de escribir. Pero puede haber más casos extremos de los que son inmediatamente evidentes, y hay compatibilidad con IPv6 para considerar, etc. ¿Existe una biblioteca que lo haga?¿Cómo se determina si una dirección IP es privada en Python?
Respuesta
Eche un vistazo al módulo IPy. Si tiene una función iptype()
que parece hacer lo que quiere:
>>> from IPy import IP
>>> ip = IP('127.0.0.0/30')
>>> ip.iptype()
'PRIVATE'
Si desea evitar la importación de un módulo sólo se puede aplicar una expresión regular simple:.
- ^127 \ d {1, 3}. \ D {1,3}. \ D {1,3} $
- ^10. \ D {1,3}. \ D {1,3}. \ D {1,3} $
- ^192.168. \ D {1,3} $
- ^172. (1 [6-9] | 2 [0-9] | 3 [0-1]). [0-9] {1, 3}. [0-9] {1,3} $
No deberían esos. los caracteres escapan vía \. ? Supongo que el patrón seguirá funcionando de cualquier manera. –
Esa expresión regular no funcionó para mí, pero si sustituyes {123} por {1,3} funciona bien. – Tk421
Unos días después de hacer esta pregunta, me enteré de este proyecto de Google, ipaddr-py, que parece tener algunas de las mismas funcionalidades con respecto a determinar si una dirección es privada (is_rfc1918
). Aparentemente esto será estándar en Python 3.1.
Ahora es provisional en 3.3, vea el módulo [ipaddress] [1]. [1]: http://docs.python.org/3.3/library/ipaddress.html –
Consulte la propiedad "is_private". –
Puede verificarlo usted mismo usando http://tools.ietf.org/html/rfc1918 y http://tools.ietf.org/html/rfc3330. Si tiene 127.0.0.1 solo necesita &
con la máscara (digamos 255.0.0.0
) y vea si el valor coincide con cualquiera de los network address de la red privada. Así, utilizando inet_pton que puede hacer: 127.0.0.1 & 255.0.0.0 = 127.0.0.0
Aquí está el código que ilustra que:
from struct import unpack
from socket import AF_INET, inet_pton
def lookup(ip):
f = unpack('!I',inet_pton(AF_INET,ip))[0]
private = (
[ 2130706432, 4278190080 ], # 127.0.0.0, 255.0.0.0 http://tools.ietf.org/html/rfc3330
[ 3232235520, 4294901760 ], # 192.168.0.0, 255.255.0.0 http://tools.ietf.org/html/rfc1918
[ 2886729728, 4293918720 ], # 172.16.0.0, 255.240.0.0 http://tools.ietf.org/html/rfc1918
[ 167772160, 4278190080 ], # 10.0.0.0, 255.0.0.0 http://tools.ietf.org/html/rfc1918
)
for net in private:
if (f & net[1]) == net[0]:
return True
return False
# example
print(lookup("127.0.0.1"))
print(lookup("192.168.10.1"))
print(lookup("10.10.10.10"))
print(lookup("172.17.255.255"))
# outputs True True True True
otra implementación consiste en calcular los valores int de todos los bloques privados:
from struct import unpack
from socket import AF_INET, inet_pton
lookup = "127.0.0.1"
f = unpack('!I',inet_pton(AF_INET,lookup))[0]
private = (["127.0.0.0","255.0.0.0"],["192.168.0.0","255.255.0.0"],["172.16.0.0","255.240.0.0"],["10.0.0.0","255.0.0.0"])
for net in private:
mask = unpack('!I',inet_aton(net[1]))[0]
p = unpack('!I',inet_aton(net[0]))[0]
if (f & mask) == p:
print lookup + " is private"
Este es el versión fija del enfoque de expresiones regulares sugerida por @Kurt, incluida la solución recomendada por @RobEvans
- ^127. \ D {1,3}. \ D {1,3}. \ D {1,3} $
- ^10. \ D {1,3}. \ D {1,3} . \ d {1,3} $
- ^192.168. \ d {1,3}. \ d {1,3} $
^172. (1 [6-9] | 2 [0- 9] |.. 3 [0-1]) [0-9] {1,3} [0-9] {1,3} $
def is_ip_private(ip): # https://en.wikipedia.org/wiki/Private_network priv_lo = re.compile("^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$") priv_24 = re.compile("^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$") priv_20 = re.compile("^192\.168\.\d{1,3}.\d{1,3}$") priv_16 = re.compile("^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$") res = priv_lo.match(ip) or priv_24.match(ip) or priv_20.match(ip) or priv_16.match(ip) return res is not None
+1, sugiero que se devuelva un "contenedor" booleano, para reflejar mejor el nombre de la función: return (priv_lo.match (ip) o priv_24.match (ip) o priv_20.match (ip) o priv_16.match (ip)) no es Ninguno – mork
Como Python 3.3 hay un ipaddress module en el stdlib que puedes usar
>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1').is_private
True
Si usando Python 2.6 o superior no te recomiendo utilizar a backport of this module.
Encuentro esto en cuckoo. No es necesario instalar nuevos módulos. Solo importe dos módulos incorporados: socket y struct. Y usa la función a continuación.
def _is_private_ip(self, ip):
"""Check if the IP belongs to private network blocks.
@param ip: IP address to verify.
@return: boolean representing whether the IP belongs or not to
a private network block.
"""
networks = [
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.88.99.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"240.0.0.0/4",
"255.255.255.255/32",
"224.0.0.0/4",
]
for network in networks:
try:
ipaddr = struct.unpack(">I", socket.inet_aton(ip))[0]
netaddr, bits = network.split("/")
network_low = struct.unpack(">I", socket.inet_aton(netaddr))[0]
network_high = network_low | 1 << (32 - int(bits)) - 1
if ipaddr <= network_high and ipaddr >= network_low:
return True
except Exception,err:
continue
return False
- 1. cómo determinar si una dirección IP es privada?
- 2. determina programáticamente si la dirección IP se asigna mediante dhcp o se establece manualmente en java
- 3. ¿Existe una función que pueda tomar una dirección IP como cadena y decirme si es una dirección IP no enrutable?
- 4. Verificando si una variable POST [] es una dirección IP?
- 5. ¿Encontrar una dirección IP pública en Python?
- 6. IP privada identificador de dirección en la expresión regular
- 7. ¿Determina si una lista de Python es el 95% igual?
- 8. Cómo determinar si una dirección IP pertenece a un país
- 9. ¿Es 0.0.0.0 una dirección IP válida?
- 10. Compruebe si la dirección IP está en el rango privado
- 11. Detecta si la dirección IP pública es dinámica o estática
- 12. ¿Cómo es que InetAddress.getByName ("1.2") es una dirección IP válida?
- 13. Cómo validar una dirección IP en C#
- 14. Geocodificar una dirección IP?
- 15. ¿Cómo verifico si un valor de una cadena es una dirección IP
- 16. ¿Cómo comprobar si una dirección IP es el host local en un sistema de múltiples hosts?
- 17. ¿Cómo se determina si la referencia del objeto es nula?
- 18. ¿Cómo se determina si ParameterInfo es de tipo genérico?
- 19. Python: obtenga la dirección IP local utilizada para enviar datos IP a una dirección IP remota específica
- 20. ¿Cómo obtener la dirección IP cuando se crea una sesión?
- 21. ¿Es posible ocultar la dirección IP en una conexión PHP?
- 22. comprobar si una cadena coincide con un patrón de dirección IP en python?
- 23. Dirección IP en Silverlight
- 24. ¿Cómo compararías la dirección IP?
- 25. ¿Cómo se determina si CKEditor está cargado?
- 26. Cómo bloquear una dirección IP usando web.xml?
- 27. RegEx para una dirección IP
- 28. ¿Cómo se determina si una lista bidimensional contiene un valor?
- 29. ¿Cómo obtengo una dirección IP pública de un teléfono móvil?
- 30. Calcular si una dirección IP se encuentra en un rango especificado en Java
Como se esperaba para una IP pública, la cadena es 'PUBLIC'. Hay algunos resultados inesperados: 'print (IP ('127.0.0.1'). Iptype())' produce 'PRIVATE'. 'print (IP (':: 1'). iptype())' produce 'LOOPBACK'. 'print (IP ('2001: 0658: 022a: café: 0200 :: 1'). iptype())' produce 'RLOQUEO ASIGNADO NCC' –
¡Esto es perfecto! – Ryan
De hecho, hay algunos resultados inesperados: 'print (IP ('0.0.0.0/0'). Iptype()) produce 'PRIVATE', mientras que yo esperaría que" todo el Internet IPv4 "sea PÚBLICO ... – Niobos