Jaki jest najlepszy sposób sprawdzenia, czy adres IP wprowadzony przez użytkownika jest prawidłowy? Wchodzi jako ciąg.Jak sprawdzić poprawność adresu IP w Pythonie?
Odpowiedz
myślę, że to zrobi to ...
def validIP(address):
parts = address.split(".")
if len(parts) != 4:
return False
for item in parts:
if not 0 <= int(item) <= 255:
return False
return True
Możesz chcieć złapać wyjątek ValueError z int() na wypadek, gdyby użytkownik wpisze "a.b.d", a nie liczby całkowite. –
Zły kod, działa tylko z adresami IPv4. – bortzmeyer
Python's int() przymus jest zbyt luźny; na przykład usuwa spacje. –
def is_valid_ip(ip):
"""Validates IP addresses.
"""
return is_valid_ipv4(ip) or is_valid_ipv6(ip)
IPv4:
def is_valid_ipv4(ip):
"""Validates IPv4 addresses.
"""
pattern = re.compile(r"""
^
(?:
# Dotted variants:
(?:
# Decimal 1-255 (no leading 0's)
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2} # Hexadecimal 0x0 - 0xFF (possible leading 0's)
|
0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
)
(?: # Repeat 0-3 times, separated by a dot
\.
(?:
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2}
|
0+[1-3]?[0-7]{0,2}
)
){0,3}
|
0x0*[0-9a-f]{1,8} # Hexadecimal notation, 0x0 - 0xffffffff
|
0+[0-3]?[0-7]{0,10} # Octal notation, 0 - 037777777777
|
# Decimal notation, 1-4294967295:
429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
)
$
""", re.VERBOSE | re.IGNORECASE)
return pattern.match(ip) is not None
IPv6:
def is_valid_ipv6(ip):
"""Validates IPv6 addresses.
"""
pattern = re.compile(r"""
^
\s* # Leading whitespace
(?!.*::.*::) # Only a single whildcard allowed
(?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard
(?: # Repeat 6 times:
[0-9a-f]{0,4} # A group of at most four hexadecimal digits
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
){6} #
(?: # Either
[0-9a-f]{0,4} # Another group
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
[0-9a-f]{0,4} # Last group
(?: (?<=::) # Colon iff preceeded by exacly one colon
| (?<!:) #
| (?<=:) (?<!::) : #
) # OR
| # A v4 address with NO leading zeros
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
(?: \.
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
){3}
)
\s* # Trailing whitespace
$
""", re.VERBOSE | re.IGNORECASE | re.DOTALL)
return pattern.match(ip) is not None
Wersja IPv6 wykorzystuje "(?:(?<=::)|(?<!::):)
", który można zastąpić przez "(?(?<!::):)
"w przypadku silników regex, które obsługują warunkowe z rozejrzanymi widokami. (Tj PCRE, .NET)
Edit:
- Wypada rodzimą odmianę.
- Rozszerzono wyrażenie regularne, aby zachować zgodność z dokumentem RFC.
- Dodano kolejne wyrażenie do adresów IPv6.
Edit2:
znalazłem kilka linków omawianiu sposobu analizowania adresy IPv6 z regex:
- A Regular Expression for IPv6 Addresses - InterMapper Forum
- Working IPv6 regular expression - plac zabaw blog Patryka
- test-ipv6-regex.pl - Skrypt Perla z mnóstwem testów. Wygląda na to, że moje regex kończy się niepowodzeniem w przypadku kilku z tych testów.
Edit3:
Wreszcie udało się napisać wzór, który przechodzi wszystkie testy, a ja też jestem zadowolony.
Nie, działa tylko z adresami IPv4. – bortzmeyer
test-ipv6-regex.pl jest złoty +1 – Marcin
To powinna być odpowiedź, @ chills42. –
Nie parsuj tego. Po prostu zapytaj.
import socket
try:
socket.inet_aton(addr)
# legal
except socket.error:
# Not legal
Hmm, zdaje się akceptować rzeczy takie jak "4" i "192.168" i cicho podkłada resztę zerami. Technicznie ważny, jestem pewien, ale nie do końca tego, czego się spodziewałem. – krupan
Są to prawidłowe reprezentacje adresów IP. 127.1 to localhost, 1172703390 to mój serwer WWW. Jeśli chcesz upewnić się, że jest w kropkowanym kwadracie, możesz również sprawdzić, czy len (addr.split ('.')) == 4 – Dustin
@krupan: możesz połączyć powyższe z testem dla "len (addr.split (" . ")) == 4" jeśli chcesz odrzucić krótsze adresy. –
IPy module (moduł przeznaczony do czynienia z adresami IP) rzuci wyjątek ValueError dla nieprawidłowych adresów.
>>> from IPy import IP
>>> IP('127.0.0.1')
IP('127.0.0.1')
>>> IP('277.0.0.1')
Traceback (most recent call last):
...
ValueError: '277.0.0.1': single byte must be 0 <= byte < 256
>>> IP('foobar')
Traceback (most recent call last):
...
ValueError: invalid literal for long() with base 10: 'foobar'
Jednak, podobnie jak odpowiedź Dustina, będzie przyjmować takie rzeczy jak „4” i „192.168”, ponieważ, jak wspomniano, te obowiązują reprezentacje adresów IP.
Jeśli używasz Pythona 3.3 lub później, zawiera obecnie ipaddress module:
>>> import ipaddress
>>> ipaddress.ip_address('127.0.0.1')
IPv4Address('127.0.0.1')
>>> ipaddress.ip_address('277.0.0.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: '277.0.0.1' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.ip_address('foobar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: 'foobar' does not appear to be an IPv4 or IPv6 address
dla Pythona 2, można uzyskać taką samą funkcjonalność korzystania adresip jeśli zainstalować python-adres_IP
pip install ipaddress
Moduł ten jest kompatybilny z Pythonie 2 i zapewnia bardzo podobny interfejs API do modułu ipaddress zawartego w Python Standard Library od wersji Python 3.3. Więcej szczegółów here. W Pythonie 2 będziesz musiał jawnie przekonwertować ciąg adresu IP na kod Unicode: ipaddress.ip_address(u'127.0.0.1')
.
Doskonały pomysł. Jedyne dotychczasowe rozwiązanie, które działa ze wszystkimi adresami IP. >>> od IPy import IP >>> IP ("2001: 660 :: 1") IP ('2001: 660 :: 1') – bortzmeyer
Dla Pythona 2, zainstaluj pip ipad i otrzymasz prawie to samo API :) – radtek
Odnośnie 'import ipaddress', kiedy przekazałem adres IPv4, otrzymałem wynik podobny do' IPv4Address ('127.0.0.1') '. Ale kiedy próbowałem przekonwertować go na 'string', aby sprawdzić, czy zawiera on' IPv4' lub 'IPv6', właśnie dostałem adres IP. Skąd mam wiedzieć w kodzie, czy jest to 'IPv4' lub' IPv6'? Czy 'if" IPv4 "w str (typ (val)):' dobry pomysł? – Gauranga
import socket
def is_valid_ipv4_address(address):
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
def is_valid_ipv6_address(address):
try:
socket.inet_pton(socket.AF_INET6, address)
except socket.error: # not a valid address
return False
return True
Dlaczego linia: "return address.count ('.') == 3" ?? Czy to pozostało po debugowaniu? – quux
@quux: nie. To długa dyskusja, a ludzie nie lubią tego, że przynajmniej skrócone adresy Linux i Windows są uznawane za dopuszczalne. Na przykład 'socket.inet_aton ('127.1')' zwraca wartość ''\ x7f \ x00 \ x00 \ x01'' (czyli dokładnie tak, jak" 127.0.0.1 "). Miałem tę męczącą i długotrwałą dyskusję gdzie indziej na SO, ale nie mogę sobie przypomnieć gdzie. – tzot
Dzięki. Nie wiedziałem tego! – quux
Od Pythona 3.4, najlepszym sposobem, aby sprawdzić, czy adres IPv4 lub IPv6 jest poprawna, jest użycie modułu Python biblioteki standardowej ipaddress
- IPv4/IPv6 biblioteki manipulacji S.A. https://docs.python.org/3/library/ipaddress.html dla pełnej dokumentacji.
przykład:
#!/usr/bin/env python
import ipaddress
import sys
try:
ip = ipaddress.ip_address(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]
W innych wersjach Github, phihag/Philipp Hagemeister "Python 3,3 za adresip starszych wersji Pythona", https://github.com/phihag/ipaddress
backporty z phihag dostępne np w Anacondzie Python 2.7 & jest zawarty w Instalatorze. s.a. https://docs.continuum.io/anaconda/pkg-docs
Aby zainstalować z pip:
pip install ipaddress
SA: adresip 1.0.17 "IPv4/IPv6 biblioteka manipulacja", "Port w 3.3+ modułu ipaddress" https://pypi.python.org/pypi/ipaddress/1.0.17
Sugeruję, abyś edytował swoją odpowiedź określając wersję (wersje) Pythona, że ten moduł jest dołączony do stdlib. – tzot
@tzot ktos powinien rozwiazac Python 2.x i wszelkiego rodzaju fajne rzeczy do niego z 3.x bibliotek, a nawet rdzenia. MOIM ZDANIEM. –
Otrzymuję ten błąd 'C: \ Python \ Codes> check_ip.py Plik" C: \ Python \ Codes \ check_ip.py ", wiersz 8 print '% s jest prawidłowym adresem IP% s. " % (ip, ip.version) ^ Błąd składni: nieprawidłowa składnia C: \ Python \ Kody> ' – Sabrina
muszę Markusowi Jarderotowi przydaj się na jego stanowisko - większość mojego postu jest zainspirowana jego.
Zauważyłem, że odpowiedź Markusa wciąż zawodzi w niektórych przykładach IPv6 w skrypcie Perla, do którego odnosi się jego odpowiedź.
Oto mój regex, która przechodzi wszystkie przykłady w tym Perl skryptu:
r"""^
\s* # Leading whitespace
# Zero-width lookaheads to reject too many quartets
(?:
# 6 quartets, ending IPv4 address; no wildcards
(?:[0-9a-f]{1,4}(?::(?!:))){6}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-5 quartets, wildcard, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
(?:::(?!:))
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-4 quartets, wildcard, 0-1 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:)))?
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-3 quartets, wildcard, 0-2 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,2}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-2 quartets, wildcard, 0-3 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,3}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-1 quartets, wildcard, 0-4 quartets, ending IPv4 address
(?:[0-9a-f]{1,4}){0,1}
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,4}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# wildcard, 0-5 quartets, ending IPv4 address
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,5}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 8 quartets; no wildcards
(?:[0-9a-f]{1,4}(?::(?!:))){7}[0-9a-f]{1,4}
|
# 0-7 quartets, wildcard
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,6}[0-9a-f]{1,4})?
(?:::(?!:))
|
# 0-6 quartets, wildcard, 0-1 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,5}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4})?
|
# 0-5 quartets, wildcard, 0-2 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
|
# 0-4 quartets, wildcard, 0-3 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
|
# 0-3 quartets, wildcard, 0-4 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
|
# 0-2 quartets, wildcard, 0-5 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
|
# 0-1 quartets, wildcard, 0-6 quartets
(?:[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,5}[0-9a-f]{1,4})?
|
# wildcard, 0-7 quartets
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,6}[0-9a-f]{1,4})?
)
(?:/(?:1(?:2[0-7]|[01]\d)|\d\d?))? # With an optional CIDR routing prefix (0-128)
\s* # Trailing whitespace
$"""
ja również ułożyła skrypt Pythona do przetestowania wszystkich tych przykładach IPv6; to jest here on Pastebin, ponieważ była zbyt duża, aby ją opublikować.
można uruchomić skrypt z wynikiem testu i przykładowych argumentów w postaci „[wynik] = [przykład]”, tak jak:
python script.py Fail=::1.2.3.4: pass=::127.0.0.1 false=::: True=::1
lub można po prostu uruchomić wszystkie testy, określając żadnych argumentów, więc jak:
python script.py
W każdym razie, mam nadzieję, że to pomoże komuś innemu!
+1 za wysiłek :) –
Chociaż podziwiam również twój wysiłek, myślę, że w twoim konstruktorze jest ogromna wada konstrukcyjna: Jest za duża! Nigdy bym nie ufał regexowi tej wielkości, który nie był używany przez tysiące ludzi od lat. – erikbwork
@ erikb85: Rzuć okiem na skrypt, który zamieściłem w Pastebin. Zawiera 1154 testów różnych formatów IPv6 i przekazuje ** każdy ** ** z nich. Jeśli uważasz, że potrzebujesz więcej testów, możesz zmodyfikować mój skrypt, dodać testy i opublikować wyniki. – blag
Musiałem tylko sparsować adresy IP v4.Moje rozwiązanie opiera się na strategii dreszcze następująco:
def getIP():
valid = False
while not valid :
octets = raw_input("Remote Machine IP Address:").strip().split(".")
try: valid=len(filter(lambda(item):0<=int(item)<256, octets)) == 4
except: valid = False
return ".".join(octets)
Mam nadzieję, że to proste i dość pythonic:
def is_valid_ip(ip):
m = re.match(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$", ip)
return bool(m) and all(map(lambda n: 0 <= int(n) <= 255, m.groups()))
wymyśliłem ten noob prosta wersja
def ip_checkv4(ip):
parts=ip.split(".")
if len(parts)<4 or len(parts)>4:
return "invalid IP length should be 4 not greater or less than 4"
else:
while len(parts)== 4:
a=int(parts[0])
b=int(parts[1])
c=int(parts[2])
d=int(parts[3])
if a<= 0 or a == 127 :
return "invalid IP address"
elif d == 0:
return "host id should not be 0 or less than zero "
elif a>=255:
return "should not be 255 or greater than 255 or less than 0 A"
elif b>=255 or b<0:
return "should not be 255 or greater than 255 or less than 0 B"
elif c>=255 or c<0:
return "should not be 255 or greater than 255 or less than 0 C"
elif d>=255 or c<0:
return "should not be 255 or greater than 255 or less than 0 D"
else:
return "Valid IP address ", ip
p=raw_input("Enter IP address")
print ip_checkv4(p)
Rozważmy adresowej IPv4 jako " ip ".
if re.match(r'^((\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])$', ip):
print "Valid IP"
else:
print "Invalid IP"
- 1. Jak sprawdzić poprawność adresu IP za pomocą wyrażenia regularnego w Objective-C?
- 2. Jak sprawdzić poprawność adresu URL w jquery przy użyciu Regex?
- 3. Symfony2 - Jak sprawdzić poprawność adresu e-mail w kontrolerze
- 4. Jak sprawdzić poprawność formatu ciągu daty w pythonie?
- 5. Jak sprawdzić poprawność struktury (lub schematu) słownika w Pythonie?
- 6. Jak sprawdzić poprawność tablicy?
- 7. Jak sprawdzić poprawność wyrażenia regularnego?
- 8. Jak sprawdzić poprawność xml z php
- 9. Jak sprawdzić poprawność daty MYSQL w PHP?
- 10. Jak sprawdzić poprawność wybranej wartości w DropDownList?
- 11. Jak sprawdzić poprawność obiektu JSON w java?
- 12. Jak sprawdzić poprawność pola wyboru w nokaucie
- 13. Znajdowanie adresu IP użytkownika
- 14. Jak sprawdzić, czy IP jest publicznym proxy?
- 15. Przekierowywanie adresu IP w Javie
- 16. Uzyskiwanie lokalnego adresu IP
- 17. przycinanie adresu IP oktet
- 18. Jak "sprawdzić poprawność" NSTimer po unieważnieniu go?
- 19. Elixir Ecto: Jak sprawdzić poprawność klucza obcego?
- 20. Jak sprawdzić poprawność dwóch pól dla unikalności
- 21. Jak mogę sprawdzić poprawność wyjścia XmlSerializer?
- 22. Jak sprawdzić poprawność XHTML za pomocą nokogiri?
- 23. jak sprawdzić poprawność identyfikatora powiązanego modelu?
- 24. Jak sprawdzić poprawność aktualizacji przed instalacją
- 25. Jak sprawdzić poprawność formatowania adresu e-mail w środowisku .NET Framework?
- 26. Jak sprawdzić poprawność adresu URL w java za pomocą wyrażeń regularnych?
- 27. Jak sprawdzić poprawność pliku xml na schemacie XSD przy użyciu biblioteki Amara w Pythonie?
- 28. Sprawdzanie poprawności adresu IP (z maską)
- 29. Zobacz, jak zmienia się stan adresu IP.
- 30. Konwersja adresu IP na numer:
Chcę tylko zwrócić uwagę, że jeśli adres rozgłoszeniowy nie jest uznawany za prawidłowy adres, to każde z proponowanych rozwiązań zawodzi. Musisz przetestować maskę podsieci, aby sprawdzić, czy jest to adres rozgłoszeniowy. – Bitt