John
John

Reputation: 89

Comparing a list and extracting a number

I am trying to take a list that contains IP address' with subnet masks (1.0.0.0/24) and calculating the total number of IP address' in that list. However, I am trying to avoid calculating the same IP address' but have a higher subnet mask.

Example 1.0.0.0/24 1.0.0.0/16 1.0.0.0/8

Here I would only want to use the /8 to calculate the IP address because is contains /16 and /24

I have put all of the IP address in a list, newSet, like so...

Example 1.0.0.0/24 1.0.0.0/16 1.0.0.0/8 2.0.0.0/24 2.0.0.0/16 etc....

then I use the following code to pop off the subnet mask /24, /16, /8 etc... like so

subIP = [i.split('/', 1)[1] for i in newSet]

Then I calculate the IP space by ipTotal is declared globally

for element in subIP:
   y = 32 - int(element)
   x = pow(2, y)
   ipTotal = ipTotal + x 

however I am now calculating 1.0.0.0/24 , 1.0.0.0/16, and 1.0.0.0/8 when all I need to do is calculate 1.0.0.0/8.

Basically I am over calculating the amount of IP space.

How do I need to approach this? I thought about putting the 1.0.0.0 into a list, then putting the /24 into another list... then running a nested for loop to compare but I pretty sure this won't work.

Upvotes: 1

Views: 74

Answers (2)

Farmer Joe
Farmer Joe

Reputation: 6070

ip_dict = {}
for ip_subnet in newSet:
    ip,subnet = ip_subnet.split('/')
    subnet = int(subnet)
    if ip not in ip_dict or ip_dict[ip] > subnet:
        ip_dict[ip] = subnet
updated_list = [str(ip)+"/"+str(subnet) for ip,subnet in ip_dict.iteritems()]

ipTotal = 0
for subnet in ip_dict.values():
    y = 32 - int(subnet)
    x = pow(2, y)
    ipTotal = ipTotal + x 

You use a dictionary which is great for unique key,value pairing and just do the checks you would like, then form reconstitue the address back into a list.

updated_list will be a list of the unique IP addresses that have the smallest subnet for that IP.

ip_dict.values() gives a list of the subnets of those unique IPs.

Upvotes: 1

vsh
vsh

Reputation: 160

You should parse the list of ip/subnet into a dict, with ip as key and a set of subnet as value. You would then iterate over the keys, find the min value on the set of subnets, and apply your calculation to only that ip/subnet.

Something like this:

import collections

ip_subnet_list=['1.0.0.0/31', '1.0.0.0/30', '5.0.0.0/22']
data = collections.defaultdict(set)
for item in ip_subnet_list:
  ip, subnet = item.split('/')
  data[ip].add(int(subnet))

ip_count = 0
for ip, subnets in data.iteritems():
  subnet = min(subnets)
  ip_count += pow(2, 32 - subnet)
print ip_count

Upvotes: 0

Related Questions