如何在Python中validationIP地址?

validation用户input的IP有效的最佳方法是什么? 它以stringforms出现。

不要parsing它。 请问。

import socket try: socket.inet_aton(addr) # legal except socket.error: # Not legal 
 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 

IPy模块 (用于处理IP地址的模块)将为无效地址引发ValueErrorexception。

 >>> 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' 

但是,就像达斯汀的回答一样,它会接受像“4”和“192.168”这样的东西,因为如前所述,这些是IP地址的有效表示。

如果您使用Python 3.3或更高版本,现在它包含ipaddress模块 :

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

对于Python 2,如果您安装了python-ipaddress,则可以使用ipaddress获得相同的function:

 pip install ipaddress 

该模块与Python 2兼容,并提供了一个非常类似于自Python 3.3以来Python标准库中包含的ipaddress模块​​的API。 更多细节在这里 。

 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 

IPv6版本使用“ (?:(?<=::)|(?<!::):) ”,在正则expression式引擎上可以replace为“ (?(?<!::):) ”条件与查找。 (即PCRE,.NET)

编辑:

  • 丢弃了本地变体。
  • 扩展了正则expression式以符合RFC。
  • 为IPv6地址添加了另一个正则expression式。

EDIT2:

我发现一些链接讨论如何用正则expression式parsingIPv6地址:

  • IPv6地址的正则expression式 – InterMapper论坛
  • 使用IPv6正则expression式 – 帕特里克的操场博客
  • test-ipv6-regex.pl – 带有大量testing用例的Perl脚本。 看来我的正则expression式在一些testing上失败了。

EDIT3:

最后设法写出了一个通过所有testing的模式,而且我也很满意。

从Python 3.4开始,检查IPv6或IPv4地址是否正确的最佳方法是使用Python标准库模块ipaddress – IPv4 / IPv6操作库sa https://docs.python.org/3/library/ipaddress .html的完整文档。

例如:

 #!/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] 

对于其他版本:Github,phihag / Philipp Hagemeister,“Python 3.3的Python版本的ipaddress”, https://github.com/phihag/ipaddress

phihag的backport可以在Anaconda Python 2.7中find,包含在Installer中。 sa https://docs.continuum.io/anaconda/pkg-docs

用pip安装:

 pip install ipaddress 

sa:ipaddress 1.0.17,“IPv4 / IPv6操作库”,“3.3+ ipaddress模块​​的端口”, https: //pypi.python.org/pypi/ipaddress/1.0.17

我希望它很简单,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())) 

我想这会做到这一点…

 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 

我必须对马库斯·贾德罗德(Markus Jarderot)的职位给予很大的信任 – 我的post大部分是从他的启发。

我发现Markus的答案在他的回答中所引用的Perl脚本中仍然失败了。

这是我的正则expression式,通过该Perl脚本中的所有例子:

 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 $""" 

我还组装了一个Python脚本来testing所有这些IPv6示例; 它在这里在Pastebin,因为它太大,不能在这里发布。

你可以用“[result] = [example]”的forms运行testing结果和例子参数的脚本,例如:

 python script.py Fail=::1.2.3.4: pass=::127.0.0.1 false=::: True=::1 

或者你可以简单地运行所有的testing,通过指定没有参数,如:

 python script.py 

无论如何,我希望这可以帮助别人!

将IPv4地址视为“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" 

我只需要parsingIP v4地址。 我基于寒战战略的解决scheme如下:

 def getIP(): 
有效=假
而无效:
octets = raw_input(“Remote Machine IP Address:”).strip()。split(“。”)
try:valid = len(filter(lambda(item):0 <= int(item)<256,octets))== 4
除了:valid = False
返回“。”join(octets)

我想出了这个简单的版本

 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)