Conversión entre enteros de 32 bits y direcciones IPv4 con Python
Aprende a implementar funciones para convertir enteros de 32 bits en direcciones IPv4 y viceversa, útiles para el procesamiento de red y la seguridad.
InSkillCoach
Introducción
En el ámbito de las redes informáticas, las direcciones IPv4 se representan generalmente como una cadena de caracteres comprensible para las personas (p. ej., 192.168.1.1). Sin embargo, a nivel de máquina, estas direcciones se almacenan y manipulan como enteros de 32 bits. La conversión entre estas dos representaciones es una operación fundamental para numerosas aplicaciones de red, de seguridad y de administración de sistemas.
En este tutorial vamos a explorar cómo:
- Convertir una dirección IPv4 en un entero de 32 bits
- Convertir un entero de 32 bits en una dirección IPv4
- Aplicar estas conversiones en casos prácticos
Bases teóricas
Una dirección IPv4 se compone de 4 octetos (32 bits en total). Cada octeto puede tomar un valor entre 0 y 255. Cuando visualizamos una dirección como 192.168.1.1, en realidad estamos viendo la representación decimal con puntos del valor binario 11000000.10101000.00000001.00000001.
Para convertir esta dirección en un único entero, podemos utilizar la siguiente fórmula:
entier = (octet1 * 256³) + (octet2 * 256²) + (octet3 * 256¹) + (octet4 * 256⁰)
Lo que equivale a:
entier = (octet1 << 24) | (octet2 << 16) | (octet3 << 8) | octet4
Implementación en Python
Convertir una dirección IPv4 en entero
def ip_to_int(ip_address):
"""
Convierte una dirección IPv4 en un entero de 32 bits.
Args:
ip_address (str): Dirección IPv4 en formato '192.168.1.1'
Returns:
int: Representación entera de la dirección IPv4
"""
octets = ip_address.split('.')
# Verificación de la validez de la dirección IP
if len(octets) != 4:
raise ValueError("Format d'adresse IPv4 invalide")
# Conversión de los octetos a enteros y verificación de los rangos
octets_int = []
for octet in octets:
o = int(octet)
if o < 0 or o > 255:
raise ValueError(f"Valeur d'octet invalide: {o}")
octets_int.append(o)
# Cálculo del entero final
return (octets_int[0] << 24) | (octets_int[1] << 16) | (octets_int[2] << 8) | octets_int[3]
Convertir un entero en dirección IPv4
def int_to_ip(ip_int):
"""
Convierte un entero de 32 bits en una dirección IPv4.
Args:
ip_int (int): Entero de 32 bits que representa una dirección IPv4
Returns:
str: Dirección IPv4 en formato '192.168.1.1'
"""
# Verificación del rango válido para una dirección IPv4
if ip_int < 0 or ip_int > 4294967295: # 2^32 - 1
raise ValueError("L'entier doit être compris entre 0 et 2^32 - 1")
# Extracción de los octetos
octet1 = (ip_int >> 24) & 255
octet2 = (ip_int >> 16) & 255
octet3 = (ip_int >> 8) & 255
octet4 = ip_int & 255
# Construcción de la dirección IP
return f"{octet1}.{octet2}.{octet3}.{octet4}"
Ejemplos de uso
Estos son algunos ejemplos para demostrar el uso de estas funciones:
# Conversión de IP a entero
print(ip_to_int("192.168.1.1")) # Output: 3232235777
print(ip_to_int("127.0.0.1")) # Output: 2130706433
print(ip_to_int("10.0.0.1")) # Output: 167772161
# Conversión de entero a IP
print(int_to_ip(3232235777)) # Output: 192.168.1.1
print(int_to_ip(2130706433)) # Output: 127.0.0.1
print(int_to_ip(167772161)) # Output: 10.0.0.1
Uso de la biblioteca estándar
Python también ofrece una solución mediante el módulo socket de la biblioteca estándar para realizar estas conversiones:
import socket
import struct
# Conversión de IP a entero
def ip_to_int_socket(ip_address):
return struct.unpack('!I', socket.inet_aton(ip_address))[0]
# Conversión de entero a IP
def int_to_ip_socket(ip_int):
return socket.inet_ntoa(struct.pack('!I', ip_int))
# Ejemplos
print(ip_to_int_socket("192.168.1.1")) # Output: 3232235777
print(int_to_ip_socket(3232235777)) # Output: 192.168.1.1
Este enfoque es más conciso y gestiona automáticamente la validación de las direcciones IP.
Aplicaciones prácticas
1. Verificación de pertenencia a una subred
def is_in_subnet(ip, subnet, mask):
"""
Verifica si una dirección IP pertenece a una subred.
Args:
ip (str): Dirección IP que se va a verificar
subnet (str): Dirección de la subred
mask (int): Máscara de subred en notación CIDR (p. ej.: 24 para /24)
Returns:
bool: True si la IP pertenece a la subred, False en caso contrario
"""
ip_int = ip_to_int(ip)
subnet_int = ip_to_int(subnet)
# Creación de la máscara binaria
cidr_mask = (0xFFFFFFFF << (32 - mask)) & 0xFFFFFFFF
# Comparación de las redes
return (ip_int & cidr_mask) == (subnet_int & cidr_mask)
# Ejemplo
print(is_in_subnet("192.168.1.5", "192.168.1.0", 24)) # Output: True
print(is_in_subnet("192.168.2.1", "192.168.1.0", 24)) # Output: False
2. Iteración sobre un bloque de direcciones IP
def ip_range(start_ip, end_ip):
"""
Genera todas las direcciones IP de un rango dado.
Args:
start_ip (str): Dirección IP inicial
end_ip (str): Dirección IP final
Yields:
str: Direcciones IP del rango
"""
start_int = ip_to_int(start_ip)
end_int = ip_to_int(end_ip)
if start_int > end_int:
raise ValueError("L'adresse IP de début doit être inférieure à l'adresse IP de fin")
for ip_int in range(start_int, end_int + 1):
yield int_to_ip(ip_int)
# Ejemplo
for ip in ip_range("192.168.1.1", "192.168.1.5"):
print(ip)
# Output:
# 192.168.1.1
# 192.168.1.2
# 192.168.1.3
# 192.168.1.4
# 192.168.1.5
Rendimiento y optimizaciones
Para las aplicaciones que requieren numerosas conversiones, las funciones pueden optimizarse:
# Versión optimizada sin validación
def ip_to_int_fast(ip_address):
a, b, c, d = map(int, ip_address.split('.'))
return (a << 24) | (b << 16) | (c << 8) | d
def int_to_ip_fast(ip_int):
return f"{(ip_int >> 24) & 255}.{(ip_int >> 16) & 255}.{(ip_int >> 8) & 255}.{ip_int & 255}"
Estas versiones sacrifican la validación en favor del rendimiento, por lo que solo deben utilizarse en contextos en los que las entradas ya estén validadas.
Conclusión
La conversión entre direcciones IPv4 y enteros de 32 bits es una operación fundamental en numerosos ámbitos relacionados con las redes informáticas. Python ofrece varios enfoques para realizar estas conversiones, desde la implementación manual hasta el uso de la biblioteca estándar.
Estas funciones pueden integrarse en diversas herramientas de red como:
- Escáneres de red
- Herramientas de análisis de logs
- Sistemas de detección de intrusiones
- Aplicaciones de monitorización de red
Al dominar estas conversiones, dispones de una competencia esencial para el desarrollo de aplicaciones de red en Python.
Acerca de InSkillCoach
Experto en formación y tecnologías
Coach especializado en tecnologías avanzadas e IA, impulsado por GNeurone Inc.
Certificaciones:
- AWS Certified Solutions Architect – Professional
- Certificaciones de Google Cloud
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Comentarios
Los comentarios funcionan con GitHub Discussions
Inicia sesión con GitHub para participar en la discusión