Skip to content

Instantly share code, notes, and snippets.

@nrdmn
Last active February 9, 2024 13:57
Show Gist options
  • Save nrdmn/f53b05d34800535a6bc4c60dfa6ac211 to your computer and use it in GitHub Desktop.
Save nrdmn/f53b05d34800535a6bc4c60dfa6ac211 to your computer and use it in GitHub Desktop.
collapse a list of IP addresses
#!/usr/bin/python3
# reads a list of IP subnets in CIDR notation from stdin and collapses it
import sys
import ipaddress
subnets6 = []
subnets4 = []
input_list = sys.stdin.readlines()
# parse subnets
for net in input_list:
try:
n = ipaddress.ip_network(net.strip())
if n.version == 4:
subnets4.append(n)
else:
subnets6.append(n)
except ValueError:
pass
for subnets in [subnets6, subnets4]:
# remove duplicates
subnets = list(set(subnets))
# sort
subnets.sort()
# remove smaller subnets of larger ones
lensubnets = len(subnets)
i = 0
while i < lensubnets-1:
j = i+1
while j <= lensubnets-1:
if subnets[i].overlaps(subnets[j]):
subnets.remove(subnets[j])
lensubnets -= 1
else:
break
i += 1
# collapse neighbors
i = 0
while i < lensubnets-1:
j = i+1
while j <= lensubnets-1:
if subnets[i].prefixlen == subnets[j].prefixlen and subnets[i].supernet().overlaps(subnets[j]):
subnets[i] = subnets[i].supernet()
subnets.pop(j)
lensubnets -= 1
if i > 0:
i -= 1
j -= 1
else:
break
i += 1
for net in subnets:
print(net.with_prefixlen)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment