Esistono librerie esistenti per analizzare una stringa come indirizzo ipv4 o ipv6 o almeno per identificare se una stringa è un indirizzo IP (di entrambi i tipi)?Controllo degli indirizzi IP
risposta
Sì, c'è il modulo ipaddr
, che può aiutare a verificare se una stringa è un indirizzo IPv4/IPv6 e rilevare la sua versione.
import ipaddr
import sys
try:
ip = ipaddr.IPAddress(sys.argv[1])
print '%s is a correct IP%s address.' % (ip, ip.version)
except ValueError:
print 'address/netmask is invalid: %s' % sys.argv[1]
except:
print 'Usage : %s ip' % sys.argv[0]
Ma questo non è un modulo standard, quindi non è sempre possibile usarlo. È anche provare a utilizzare il modulo standard socket
:
import socket
try:
socket.inet_aton(addr)
print "ipv4 address"
except socket.error:
print "not ipv4 address"
Per indirizzi IPv6 è necessario utilizzare socket.inet_pton(socket.AF_INET6, address)
.
Vorrei anche notare che inet_aton
proverà a convertire (e veramente convertirlo) indirizzi come 10
, 127
e così via, che non assomigliano a indirizzi IP.
ipaddr - Pacchetto di manipolazione degli indirizzi IP di Google.
Si noti che una proposta di includere una versione rivista del pacchetto nella libreria standard Python è stata recentemente accettata (vedere PEP 3144).
notare che, mentre questa libreria in effetti è stato accettato per l'inclusione nella libreria standard, non è incluso in ogni versione Python ancora stabile.(Naturalmente è ancora possibile installare la versione PyPI.) –
@Sven Marnach - buon punto, ho modificato per riflettere questo. – Ghopper21
per IPv4 È possibile utilizzare
socket.inet_aton(some_string)
se viene generata un'eccezione, some_string
non è un indirizzo IP valido
Per IPv6, è possibile utilizzare:
socket.inet_pton(socket.AF_INET6, some_string)
ancora una volta, genera un'eccezione se some_string
non è un indirizzo valido
Questo funziona solo con Indirizzi IPv4, però. –
@Sven, ho aggiunto un modo per la v6, è solo un po 'più complicato –
Oh, non ne ero a conoscenza. Penso che questa sia la soluzione migliore ancora - eliminerò la mia. –
soluzione IPv4 + IPv6 contando solo sulle libreria standard. Restituisce 4
o 6
o alza ValueError
.
try:
# Python 3.3+
import ipaddress
def ip_kind(addr):
return ipaddress.ip_address(addr).version
except ImportError:
# Fallback
import socket
def ip_kind(addr):
try:
socket.inet_aton(addr)
return 4
except socket.error: pass
try:
socket.inet_pton(socket.AF_INET6, addr)
return 6
except socket.error: pass
raise ValueError(addr)
Se si sa per certo che l'indirizzo è valido e solo cercando di decidere se sia IPv4 o IPv6, non sarebbe sufficiente a fare proprio:
if ":" in address:
print("Ipv6")
else:
print("Ipv4")
Non sapevo che fosse un IP. Dovevo controllare se si trattava di un IP. Ho aggiornato la domanda per chiarezza. – Rory
È possibile utilizzare il Libreria netaddr
. Ha metodi valid_ipv4/valid_ipv6:
import netaddr
if netaddr.valid_ipv4(str_ip) is True:
print("IP is IPv4")
else:
if netaddr.valid_ipv6(str_ip) is True:
print("IP is IPv6")
preferisco ip_interface perché gestisce le situazioni con e senza maschera prefisso, per esempio, sia "10.1.1.1/24" così come semplicemente "10.1.1.1". Inutile dire che funziona per entrambi V4 così come v6
from ipaddress import ip_interface
ip_interface("10.1.1.1/24").ip
ip_interface("10.1.1.1/24").ip.version
ip_interface("10.1.1.1").ip
ip_interface("10.1.1.1").ip.version
AttributeError: l'oggetto 'module' non ha attributo 'ip_address' – Rory
@Blazemore: nelle nuove versioni del modulo usa 'IPAddress'; fissai la mia risposta; grazie per il suggerimento! –
Solo per aggiungere un po 'di background, il socket impl è molto più veloce. L'implementazione del socket – marcinkuzminski