Python에서 IP 주소를 검증하는 방법은 무엇입니까?
사용자가 입력한 IP가 유효한지 확인하는 가장 좋은 방법은 무엇입니까?끈으로 되어 있습니다.
해석하지 마세요.그냥 물어보세요.
import socket
try:
socket.inet_aton(addr)
# legal
except socket.error:
# Not legal
Python 3.4부터는 IPv6 또는 IPv4 주소가 올바른지 확인하는 가장 좋은 방법은 Python Standard Library 모듈을 사용하는 것입니다.ipaddress
전체 문서를 보려면 IPv4/IPv6 조작 라이브러리 s.a. 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, pihag / Philipp Hagemeister "Python 3.3의 이전 Python 버전의 IP 주소", https://github.com/phihag/ipaddress
Phihag의 백포트는 예를 들어 Anaconda Python 2.7에서 사용할 수 있으며 Installer. s.a. https://docs.continuum.io/anaconda/pkg-docs 에 포함되어 있습니다.
pip을 사용하여 설치하는 방법:
pip install ipaddress
s.a.: ipaddress 1.0.17, "IPv4/IPv6 조작 라이브러리", "3.3+ ipaddress 모듈의 포트", https://pypi.python.org/pypi/ipaddress/1.0.17
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 주소를 처리하도록 설계된 모듈)은 잘못된 주소에 대해 ValueError 예외를 발생시킵니다.
>>> 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'
그러나, 더스틴의 답변처럼, 언급했듯이, 이것들은 IP 주소의 유효한 표현이기 때문에 "4"와 "192.168"과 같은 것들을 받아들일 것입니다.
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를 사용하여 동일한 기능을 얻을 수 있습니다.
pip install ipaddress
이 모듈은 Python 2와 호환되며 Python 3.3 이후 Python Standard Library에 포함된 ipaddress 모듈과 매우 유사한 API를 제공합니다.자세한 내용은 여기에 있습니다.Python 2에서는 IP 주소 문자열을 유니코드로 명시적으로 변환해야 합니다.ipaddress.ip_address(u'127.0.0.1')
.
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 버전은 "를 사용합니다.(?:(?<=::)|(?<!::):)
"로 대체될 수 있습니다.(?(?<!::):)
룩어라운드가 포함된 조건부를 지원하는 정규식 엔진에서.(즉, PCRE, .NET)
편집:
- 네이티브 변형을 삭제했습니다.
- RFC를 준수하도록 정규식을 확장했습니다.
- IPv6 주소에 대한 다른 정규식이 추가되었습니다.
편집 2:
regex를 사용하여 IPv6 주소를 구문 분석하는 방법에 대해 논의하는 몇 가지 링크를 찾았습니다.
- IPv6 주소 정규식 - InterMapper 포럼
- 워킹 IPv6 정규 표현 - 패트릭의 놀이터 블로그
- test-ipv6-regex.pl - 수많은 테스트 사례가 포함된 Perl 스크립트.제 정규식은 몇 가지 테스트에서 실패한 것 같습니다.
편집 3:
드디어 모든 시험에 합격한 패턴을 쓸 수 있게 되었고, 저도 만족합니다.
나는 그것이 충분히 단순하고 부정직하기를 바랍니다:
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
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"
저는 Markus Jarderot에게 그의 직책에 대해 많은 찬사를 보내야 합니다. 제 게시물의 대부분은 그의 직책에서 영감을 받았습니다.
나는 Markus의 답변이 여전히 그의 답변이 참조한 Perl 스크립트의 IPv6 예제 중 일부를 충족하지 못한다는 것을 발견했습니다.
다음은 해당 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
$"""
또한 모든 IPv6 예제를 테스트하기 위해 Python 스크립트를 작성했습니다. Pastebin에는 너무 커서 여기에 게시할 수 없습니다.
다음과 같이 테스트 결과와 예제 인수를 사용하여 스크립트를 [[result]=[capture] 형식으로 실행할 수 있습니다.
python script.py Fail=::1.2.3.4: pass=::127.0.0.1 false=::: True=::1
또는 다음과 같이 인수를 지정하지 않고 모든 검정을 실행할 수 있습니다.
python script.py
어쨌든, 저는 이것이 다른 누군가에게 도움이 되기를 바랍니다!
저는 이 간단한 버전을 생각해냈습니다.
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)
IPv4 주소만 구문 분석하면 되었습니다.Chill 전략을 기반으로 한 제 솔루션은 다음과 같습니다.
IPdefit IP():
= False =
않은 : 다음과 같습니다.
= IP . octets = raw_input("Remote Machine IP Address:" . . )
valid항목<= == 4try: valid=len(항목(항목)):0<=int(항목)<256, 옥텟) == 4
: 유효한 = ": " " " = "
을 반환합니다. "."(으)로 합니다.
언급URL : https://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python
'programing' 카테고리의 다른 글
장고 앱을 완전히 제거하는 방법은 무엇입니까? (0) | 2023.07.18 |
---|---|
대용량 데이터에서 NA를 가장 빠르게 대체할 수 있는 방법.표 (0) | 2023.07.18 |
무한 반복기에 대한 표현이 있습니까? (0) | 2023.07.18 |
C++에서 어레이 또는 std:: 벡터를 사용하면 성능 차이가 어떻게 됩니까? (0) | 2023.07.18 |
Python 반복기에서 마지막 항목을 가져오는 가장 깨끗한 방법 (0) | 2023.07.18 |