Python - Scripting

Ordinare indirizzi IP in Python

Gestire indirizzi IP come se fossero semplici stringhe è uno degli errori più comuni. Se si prova a ordinare una lista di IP alfabeticamente, non si ottiene il risultato desiderato. Ad esempio, 10.0.0.1 apparirà prima di 2.0.0.1 solo perché “1” viene prima di “2”.

Il problema risiede nel fatto che gli indirizzi IP sono composti da quattro ottetti numerici. Python, di default, ordina le stringhe carattere per carattere. Per ottenere un ordine logico (numerico), dobbiamo istruire Python a “comprendere” la struttura dell’indirizzo.

La Soluzione: Il modulo ipaddress

Dalla versione 3.3, Python include il modulo nativo ipaddress, che permette di manipolare oggetti IPv4 e IPv6 in modo sicuro. Di seguito uno script che:

  • legge l’elenco degli indirizzi IP presenti in un file
  • effettua l’ordinamento degli indirizzi IP secondo l’ordine passato come parametro
  • salva l’elenco degli indirizzi IP ordinati in un file
import ipaddress
import argparse
import sys

def main():
    # Configurazione dei parametri da riga di comando
    parser = argparse.ArgumentParser(
        description="Script per ordinare un elenco di indirizzi IP."
    )

    parser.add_argument(
        "input",
        help="Percorso del file di testo contenente gli IP da ordinare"
    )
    parser.add_argument(
        "output",
        help="Percorso del file dove salvare gli IP ordinati"
    )
    parser.add_argument(
        "--order",
        choices=['asc', 'desc'],
        default='asc',
        help="Tipo di ordinamento: 'asc' (crescente) o 'desc' (decrescente). Default: asc"
    )

    args = parser.parse_args()

    try:
        # Lettura file
        with open(args.input, 'r') as f:
            ips = [line.strip() for line in f if line.strip()]

        if not ips:
            print(f"Errore: Il file '{args.input}' è vuoto.")
            sys.exit(1)

        # Logica di ordinamento
        is_reverse = (args.order == 'desc')
        # Utilizzo di ip_address per garantire l'ordinamento numerico corretto
        ips_ordinati = sorted(ips, key=ipaddress.ip_address, reverse=is_reverse)

        # Scrittura file
        with open(args.output, 'w') as f:
            f.write('\n'.join(ips_ordinati) + '\n')

        print(f"Elaborazione completata: {len(ips_ordinati)} IP salvati in '{args.output}' ({args.order}).")

    except FileNotFoundError:
        print(f"Errore: File '{args.input}' non trovato.")
        sys.exit(1)
    except ValueError as e:
        print(f"Errore di validazione IP: {e}")
        sys.exit(1)
    except Exception as e:
        print(f"Errore imprevisto: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()

Una volta salvato il file con il nome ordinaip.py, è possibile eseguirlo specificando i parametri richiesti. Ad esempio

python ordinaip.py elenco.txt ordinato.txt

ordina gli indirizzi IP presenti nel file “elenco.txt” in ordine crescente, opzione di default qualora non venga specificata l’opzione “–order

python ordinaip.py elenco.txt ordinato.txt --order desc

ordina invece gli indirizzi IP in ordine decrescente. Lanciando lo script con l’opzione “–help

python ordinaip.py --help

viene visualizzata la guida sull’uso dello script.

Se ad esempio abbiamo il seguente elenco nel file “elenco.txt”

10.123.55.44
2.56.124.33
253.167.42.22
192.168.0.9
192.168.0.1

ed eseguiamo

python ordinaip.py elenco.txt ordinato.txt --order desc

verrà generato un file “ordinato.txt” con l’elenco degli indirizzi IP ordinati come specificato

253.167.42.22
192.168.0.9
192.168.0.1
10.123.55.44
2.56.124.33

Lo script può gestire il file di Input e Output anche in cartelle diverse specificando i percorsi nelle opzioni del comando.