다음과 같은 IP 주소 목록이 있습니다.
10.10.0.0
10.10.0.1
10.10.0.2
...
10.10.0.255
172.171.0.5
...
172.171.0.67
이러한 목록을 가져와 해당 IP 주소의 최소 CIDR 표현을 계산할 수 있는 도구가 있습니까?
예를 들어 위의 예에서는 다음과 같은 출력을 얻고 싶습니다.
10.10.0.0/24
172.171.0.5/32
172.171.0.6/31
172.171.0.8/29
172.171.0.16/28
172.171.0.32/27
172.171.0.64/30
편집: 명확히 하기 위해 "최소 CIDR 표현"은 내 입력 파일의 모든 IP 주소를 포함하는 가장 작은 CIDR IP 주소 집합입니다.
답변1
내장된 Python 모듈 사용IP 주소@AB가 제안함논평이것을 제안하다우편 엽서.
누구나주소 범위 요약(시작과 끝이 있음) 또는주소 접기(목록 포함)을 사용할 수 있습니다.
이 경우에는 후자가 더 편리합니다.
import sys
import ipaddress
data = open(sys.argv[1],'r').read().splitlines()
ips = [ipaddress.IPv4Address(line) for line in data]
print('\n'.join([ip.with_prefixlen for ip in ipaddress.collapse_addresses(ips)]))
사용법 및 출력:
$ python3 cidr.py file
10.10.0.0/24
172.171.0.5/32
172.171.0.6/31
172.171.0.8/29
172.171.0.16/28
172.171.0.32/27
172.171.0.64/30
답변2
이것은 실제로 제가 한동안 해결하고 싶은 문제입니다. 이 ipaddress
모듈을 사용하여 해결할 수 있지만 제 구현은 아마도 불필요하게 복잡할 수 있지만 작동합니다.
from ipaddress import IPv4Address, IPv6Address, IPv4Network, IPv6Network
addrs = ["10.10.0.0", "10.10.0.1", "10.10.0.2", "10.10.0.255", "172.171.0.5", "172.171.0.67"]
out = []
while True:
if len(addrs) == 0:
break
found = False
for index in out:
if IPv4Network(addrs[0], 32).subnet_of(index.supernet(new_prefix=8)):
cur = index
while True:
if cur.supernet_of(IPv4Network(addrs[0], 32)):
break
else:
cur = cur.supernet()
out[out.index(index)] = cur
addrs.pop(0)
found = True
break
if not found:
out.append(IPv4Network(addrs.pop(0), 32).supernet())
그러면 다음과 같은 결과가 나타납니다.
In [81]: out
Out[81]: [IPv4Network('10.10.0.0/24'), IPv4Network('172.171.0.0/25')]
내 구현에 대해 100% 확신할 수는 없지만 이것이 더 잘 수행될 수 있다고 생각하며 이는 /8
. 그것으로 하세요.