0%
Conversão entre inteiros de 32 bits e endereços IPv4 com Python

Conversão entre inteiros de 32 bits e endereços IPv4 com Python

Aprenda a implementar funções para converter inteiros de 32 bits em endereços IPv4 e vice-versa, úteis para processamento de rede e segurança.

I

InSkillCoach

· min

Introdução

No campo das redes de computadores, os endereços IPv4 geralmente são representados como uma string legível por humanos (ex.: 192.168.1.1). No entanto, no nível da máquina, esses endereços são armazenados e manipulados como inteiros de 32 bits. A conversão entre essas duas representações é uma operação fundamental para diversas aplicações de rede, segurança e administração de sistemas.

Neste tutorial, vamos explorar como:

  • Converter um endereço IPv4 em um inteiro de 32 bits
  • Converter um inteiro de 32 bits em um endereço IPv4
  • Aplicar essas conversões em casos práticos

Bases teóricas

Um endereço IPv4 é formado por 4 octetos (32 bits no total). Cada octeto pode assumir um valor entre 0 e 255. Quando visualizamos um endereço como 192.168.1.1, estamos na verdade vendo a representação decimal pontuada do valor binário 11000000.10101000.00000001.00000001.

Para converter esse endereço em um único inteiro, podemos usar a seguinte fórmula:

entier = (octet1 * 256³) + (octet2 * 256²) + (octet3 * 256¹) + (octet4 * 256⁰)

O que equivale a:

entier = (octet1 << 24) | (octet2 << 16) | (octet3 << 8) | octet4

Implementação em Python

Converter um endereço IPv4 em inteiro

def ip_to_int(ip_address):
    """
    Converte um endereço IPv4 em inteiro de 32 bits.
    
    Args:
        ip_address (str): Endereço IPv4 no formato '192.168.1.1'
        
    Returns:
        int: Representação inteira do endereço IPv4
    """
    octets = ip_address.split('.')
    
    # Verificação da validade do endereço IP
    if len(octets) != 4:
        raise ValueError("Format d'adresse IPv4 invalide")
    
    # Conversão dos octetos em inteiros e verificação dos intervalos
    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 do inteiro final
    return (octets_int[0] << 24) | (octets_int[1] << 16) | (octets_int[2] << 8) | octets_int[3]

Converter um inteiro em endereço IPv4

def int_to_ip(ip_int):
    """
    Converte um inteiro de 32 bits em endereço IPv4.
    
    Args:
        ip_int (int): Inteiro de 32 bits representando um endereço IPv4
        
    Returns:
        str: Endereço IPv4 no formato '192.168.1.1'
    """
    # Verificação do intervalo válido para um endereço 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")
    
    # Extração dos octetos
    octet1 = (ip_int >> 24) & 255
    octet2 = (ip_int >> 16) & 255
    octet3 = (ip_int >> 8) & 255
    octet4 = ip_int & 255
    
    # Construção do endereço IP
    return f"{octet1}.{octet2}.{octet3}.{octet4}"

Exemplos de uso

Veja alguns exemplos para demonstrar o uso dessas funções:

# Conversion IP vers entier
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

# Conversion entier vers 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 da biblioteca padrão

O Python também oferece uma solução por meio da biblioteca padrão socket para realizar essas conversões:

import socket
import struct

# Conversão de IP para inteiro
def ip_to_int_socket(ip_address):
    return struct.unpack('!I', socket.inet_aton(ip_address))[0]

# Conversão de inteiro para IP
def int_to_ip_socket(ip_int):
    return socket.inet_ntoa(struct.pack('!I', ip_int))

# Exemplos
print(ip_to_int_socket("192.168.1.1"))  # Output: 3232235777
print(int_to_ip_socket(3232235777))     # Output: 192.168.1.1

Essa abordagem é mais concisa e trata automaticamente a validação dos endereços IP.

Aplicações práticas

1. Verificação de pertencimento a uma sub-rede

def is_in_subnet(ip, subnet, mask):
    """
    Verifica se um endereço IP pertence a uma sub-rede.
    
    Args:
        ip (str): Endereço IP a verificar
        subnet (str): Endereço da sub-rede
        mask (int): Máscara de sub-rede em notação CIDR (ex: 24 para /24)
    
    Returns:
        bool: True se o IP pertence à sub-rede, False caso contrário
    """
    ip_int = ip_to_int(ip)
    subnet_int = ip_to_int(subnet)
    
    # Criação da máscara binária
    cidr_mask = (0xFFFFFFFF << (32 - mask)) & 0xFFFFFFFF
    
    # Comparação das redes
    return (ip_int & cidr_mask) == (subnet_int & cidr_mask)

# Exemplo
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. Iteração sobre um bloco de endereços IP

def ip_range(start_ip, end_ip):
    """
    Gera todos os endereços IP em um intervalo dado.
    
    Args:
        start_ip (str): Endereço IP inicial
        end_ip (str): Endereço IP final
    
    Yields:
        str: Endereços IP do intervalo
    """
    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)

# Exemplo
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

Desempenho e otimizações

Para aplicações que exigem muitas conversões, as funções podem ser otimizadas:

# Versão otimizada sem validação
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}"

Essas versões sacrificam a validação em favor do desempenho, por isso devem ser usadas apenas em contextos nos quais as entradas já foram validadas.

Conclusão

A conversão entre endereços IPv4 e inteiros de 32 bits é uma operação fundamental em diversas áreas ligadas às redes de computadores. O Python oferece várias abordagens para realizar essas conversões, desde a implementação manual até o uso da biblioteca padrão.

Essas funções podem ser integradas em diversas ferramentas de rede, como:

  • Scanners de rede
  • Ferramentas de análise de logs
  • Sistemas de detecção de intrusão
  • Aplicações de monitoramento de rede

Ao dominar essas conversões, você adquire uma competência essencial para o desenvolvimento de aplicações de rede em Python.

InSkillCoach

Sobre InSkillCoach

Especialista em treinamento e tecnologias

Coach especializado em tecnologias avançadas e IA, apoiado pela GNeurone Inc.

Certificações:

  • AWS Certified Solutions Architect – Professional
  • Certificações Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
508
244

Comentários

Os comentários são alimentados pelo GitHub Discussions

Conecte-se com o GitHub para participar da discussão

Link copiado!