programing

Python에서 IP 주소를 검증하는 방법은 무엇입니까?

lovejava 2023. 7. 18. 21:22

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 주소를 구문 분석하는 방법에 대해 논의하는 몇 가지 링크를 찾았습니다.

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