I have a list of IP addresses from an API call:
ips = ["10.135.0.80","10.135.0.81","10.135.0.83","10.135.1.200","10.135.1.220","10.160.150.2","10.160.150.7","10.255.255.2"]
I want to have a list of IP addresses that looks like:
ips = ["10.135.0.80-10.135.0.83","10.135.1.200-10.135.1.220","10.160.150.2-10.160.150.7","10.255.255.2-10.255.255.2"]
Or a result based on the suggested answer:
ips = [("10.135.0.80", "10.135.0.83"),("10.135.1.200", "10.135.1.220"),("10.160.150.2", "10.160.150.7"),("10.255.255.2","10.255.255.2")]
If the network address is equal join the smallest to largest host address. If there is one host address per network address create a range out of said host address. If the network address is different start a new element and repeat.
I've read a number of other posts where they say to use socket module and bitwise operators to sort through IP addresses which is how the original IP list gets sorted:
sortedAddresses = sorted(
ips, key=lambda ip: struct.unpack("!L", inet_aton(ip))[0]
)
The networks I can smash together really easy with some regex and make them all unique:
net = []
host = []
for ip in sortedAddresses:
l = re.split("(.*)\\.(.*)\\.(.*)\\.(.*)", ip)
net.append(l[1:-2])
host.append(l[4:-1])
networks = []
for l in net:
if l not in networks:
networks.append(l)
hosts = []
for l in host:
for e in l:
hosts.append(e)
print(networks)
print(hosts)
Print Networks:
[['10', '135', '0'], ['10', '135', '1'], ['10', '160', '150'], ['10', '255', '255']]
Print Hosts:['80', '81', '83', '200', '220', '2', '7', '2']
I think Joran's answer here with the socket module is the closest thing I've found to being my solution. I just can't figure out how I would sort through the list of hosts to determine the start and end in my original list or hosts list.
The suggested answer I received before posting is close as well except it would create to many ranges. I want the network addresses to be unique per range.
The folowing code:
import itertools
ips = [
"10.135.0.80",
"10.135.0.81",
"10.135.0.83",
"10.135.1.200",
"10.135.1.220",
"10.160.150.2",
"10.160.150.7",
"10.255.255.2",
]
for _, v in itertools.groupby(ips, lambda v: v.split(".")[:3]):
v = sorted(list(v), key=lambda x: int(x.split(".")[3]))
low = v[0]
high = v[-1]
print(f"{low}-{high}")
outputs:
10.135.0.80-10.135.0.83
10.135.1.200-10.135.1.220
10.160.150.2-10.160.150.7
10.255.255.2-10.255.255.2