Skip to content

Instantly share code, notes, and snippets.

@jurandysoares
Created November 30, 2025 21:19
Show Gist options
  • Select an option

  • Save jurandysoares/f19f63904d95ee0c8fff0cf04350ce27 to your computer and use it in GitHub Desktop.

Select an option

Save jurandysoares/f19f63904d95ee0c8fff0cf04350ce27 to your computer and use it in GitHub Desktop.
Script em Python para corrigir exercícios de análise de endereço IPv4 na notação CIDR (end. de rede, broadcast, mínimo e máximo)
#!/usr/bin/env python3
import csv
import argparse
import ipaddress
import logging
import pathlib
import re
import string
import sys
dados_rede_ip = {}
def corretor(caminho_csv: str):
csv_path = pathlib.Path(caminho_csv)
with csv_path.open(mode='r', encoding='utf-8') as arq_csv:
debug_fpath: pathlib.Path = pathlib.Path().cwd()/f"{csv_path.name[:-4]}.log"
logging.basicConfig(filename=debug_fpath, level=logging.DEBUG)
global respostas_de
global pontuacao_de
respostas_de = {}
pontuacao_de = {}
leitor_csv = csv.DictReader(arq_csv)
for linha in leitor_csv:
nome = linha['Nome']
logging.debug(f'Nome: {nome}.')
respostas_de[nome] = linha
end_ip = linha['IP']
if not end_ip in dados_rede_ip:
dados_rede_ip[end_ip] = ipcalc(end_ip)
pontuacao_de[nome] = pontuar(linha)
def pontuar(respostas: dict) -> int:
pontos = 0
pontos_bin = 0
gabarito = dados_rede_ip[respostas['IP']]
for chave in gabarito:
if chave=='BIN':
logging.debug('---')
logging.debug(gabarito[chave])
logging.debug(respostas[chave])
bits_gabarito = gabarito[chave].replace('.', '')
bits_resposta = respostas[chave].replace('.', '')
n_bits_iguais = len(['=' for i in range(32) if bits_gabarito[i]==bits_resposta[i]])
logging.debug(f"{n_bits_iguais}: {(10*n_bits_iguais/32)}")
pontos_bin = (10*n_bits_iguais/32)
pontos += pontos_bin
elif gabarito[chave]==respostas[chave]:
pontos += 10
else:
logging.debug(f"{gabarito[chave]} == {respostas[chave]} ?")
# input('Pressione ENTER para continuar.')
pontos += pontos_bin*0.75
return int(pontos)
# -----------------------------
# Validação com expressões regulares
# -----------------------------
# Regex para validar IPv4 e prefixo CIDR
CIDR_REGEX = re.compile(
r'^('
r'(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}'
r'(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])'
r'/(3[0-2]|[12]?[0-9])'
r'$'
)
def validar_cidr(entrada: str) -> bool:
return bool(CIDR_REGEX.match(entrada))
def ipv4_to_fname(ip: str) -> str:
return ip.replace('.', '_').replace('/', '_barra_')
# -----------------------------
# Conversão para binário
# -----------------------------
def ipv4_to_binary(ip: str) -> str:
octetos = ip.split('.')
return '.'.join(f"{int(o):08b}" for o in octetos)
# -----------------------------
# Função principal do ipcalc
# -----------------------------
def ipcalc(cidr: str) -> dict:
# Validação pela regex
if not validar_cidr(cidr):
print(f"Erro: '{cidr}' não é um endereço IPv4 válido em notação CIDR.")
sys.exit(1)
# Processamento usando ipaddress
network = ipaddress.ip_network(cidr, strict=False)
ip_bin = ipv4_to_binary(cidr.split('/')[0])
ip_net = network.network_address
ip_bc = network.broadcast_address
hosts = list(network.hosts())
if hosts:
first_host = hosts[0]
last_host = hosts[-1]
else:
first_host = "N/A"
last_host = "N/A"
return {
'BIN' : ip_bin,
'NET' : str(ip_net),
'BROADCAST' : str(ip_bc),
'HOST_MIN' : str(first_host),
'HOST_MAX' : str(last_host)
}
def main():
parser = argparse.ArgumentParser(
description="Corretor automático para Av06 (Endereçamento IPv4)."
)
parser.add_argument(
"csv",
type=str,
help="Arquivo CSV"
)
args = parser.parse_args()
corretor(args.csv)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment