IP 주소 (예 : 192.168.0.1)가 주어지면 Python에서 네트워크 (예 : 192.168.0.0/24)에 있는지 어떻게 확인합니까?
Python에 IP 주소 조작을위한 일반적인 도구가 있습니까? 호스트 조회, int에 대한 ip 주소, int에 대한 넷 마스크가있는 네트워크 주소 등과 같은 것들? 바라건대 2.5 용 표준 Python 라이브러리에 있습니다.
답변
이 기사 에서는 추가 노력없이 socket
및 struct
모듈로 이를 수행 할 수 있음을 보여줍니다 . 다음과 같이 기사에 약간 추가했습니다.
import socket,struct
def makeMask(n):
"return a mask of n bits as a long integer"
return (2L<<n-1) - 1
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('L',socket.inet_aton(ip))[0]
def networkMask(ip,bits):
"Convert a network address to a long integer"
return dottedQuadToNum(ip) & makeMask(bits)
def addressInNetwork(ip,net):
"Is an address in a network"
return ip & net == net
address = dottedQuadToNum("192.168.1.1")
networka = networkMask("10.0.0.0",24)
networkb = networkMask("192.168.0.0",24)
print (address,networka,networkb)
print addressInNetwork(address,networka)
print addressInNetwork(address,networkb)
결과는 다음과 같습니다.
False
True
문자열을 취하는 단일 함수를 원한다면 다음과 같습니다.
import socket,struct
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('L',socket.inet_aton(netaddr))[0] & ((2L<<int(bits)-1) - 1)
return ipaddr & netmask == netmask
답변
netaddr 을 사용하고 싶습니다 .
from netaddr import CIDR, IP
if IP("192.168.0.1") in CIDR("192.168.0.0/24"):
print "Yay!"
arno_v가 주석에서 지적했듯이 netaddr의 새 버전은 다음과 같이 수행합니다.
from netaddr import IPNetwork, IPAddress
if IPAddress("192.168.0.1") in IPNetwork("192.168.0.0/24"):
print "Yay!"
답변
사용 IPADDRESS ( 3.3부터 다음 stdlib에서를 , 2.6 / 2.7에 대한 PyPi에서 ) :
>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1') in ipaddress.ip_network('192.168.0.0/24')
True
이런 식으로 많은 IP 주소 를 평가 하려면 다음과 같이 넷 마스크를 미리 계산하는 것이 좋습니다.
n = ipaddress.ip_network('192.0.0.0/16')
netw = int(n.network_address)
mask = int(n.netmask)
그런 다음 각 주소에 대해 다음 중 하나를 사용하여 이진 표현을 계산합니다.
a = int(ipaddress.ip_address('192.0.43.10'))
a = struct.unpack('!I', socket.inet_pton(socket.AF_INET, '192.0.43.10'))[0]
a = struct.unpack('!I', socket.inet_aton('192.0.43.10'))[0] # IPv4 only
마지막으로 다음을 간단히 확인할 수 있습니다.
in_network = (a & mask) == netw
답변
python3의 경우
import ipaddress
ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/24')
ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/16')
출력 :
False
True
답변
이 코드는 Linux x86에서 나를 위해 작동합니다. 엔디 어 니스 문제에 대해서는 전혀 생각하지 않았지만, 8 개의 다른 네트워크 문자열에 대해 테스트 된 200K 이상의 IP 주소를 사용하여 “ipaddr”모듈에 대해 테스트했으며 ipaddr의 결과는이 코드와 동일합니다.
def addressInNetwork(ip, net):
import socket,struct
ipaddr = int(''.join([ '%02x' % int(x) for x in ip.split('.') ]), 16)
netstr, bits = net.split('/')
netaddr = int(''.join([ '%02x' % int(x) for x in netstr.split('.') ]), 16)
mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
return (ipaddr & mask) == (netaddr & mask)
예:
>>> print addressInNetwork('10.9.8.7', '10.9.1.0/16')
True
>>> print addressInNetwork('10.9.8.7', '10.9.1.0/24')
False
답변
Python3 ipaddress 사용 :
import ipaddress
address = ipaddress.ip_address("192.168.0.1")
network = ipaddress.ip_network("192.168.0.0/16")
print(network.supernet_of(ipaddress.ip_network(f"{address}/{address.max_prefixlen}")))
설명
IP 주소 는 가능한 가장 큰 넷 마스크를 가진 네트워크 로 생각할 수 있습니다 ( /32
IPv4의 경우, /128
IPv6의 경우)
에 있는지 확인하는 192.168.0.1
것은 192.168.0.0/16
기본적 192.168.0.1/32
으로 서브넷 인지 확인하는 것과 같습니다.192.168.0.0/16
답변
Dave Webb의 솔루션을 시도했지만 몇 가지 문제가 발생했습니다.
가장 근본적으로-일치 여부는 IP 주소를 마스크와 AND로 연결 한 다음 결과가 네트워크 주소와 정확히 일치하는지 확인해야합니다. IP 주소와 네트워크 주소를 AND로 처리하지 않았습니다.
또한 일관성이 절약된다는 가정하에 Endian 동작을 무시하는 것만으로도 옥텟 경계 (/ 24, / 16)의 마스크에 대해서만 작업 할 수 있음을 알았습니다. 다른 마스크 (/ 23, / 21)가 올바르게 작동하도록하기 위해 구조체 명령에 “보다 큼”을 추가하고 바이너리 마스크를 만드는 코드를 모두 “1”로 시작하고 왼쪽으로 (32-mask ).
마지막으로 네트워크 주소가 마스크에 유효한지 확인하고 그렇지 않은 경우 경고 만 인쇄합니다.
결과는 다음과 같습니다.
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('>L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('>L',socket.inet_aton(netaddr))[0]
ipaddr_masked = ipaddr & (4294967295<<(32-int(bits))) # Logical AND of IP address and mask will equal the network address if it matches
if netmask == netmask & (4294967295<<(32-int(bits))): # Validate network address is valid for mask
return ipaddr_masked == netmask
else:
print "***WARNING*** Network",netaddr,"not valid with mask /"+bits
return ipaddr_masked == netmask