Home > Back-end >  How can I generate a list of all possible IPs from a CIDR list in Python and assign another column t
How can I generate a list of all possible IPs from a CIDR list in Python and assign another column t

Time:06-01

I have a csv file that contains a column of CIDR IPs and a column that has the location of where that IP is being used, like this:

   | CIDR         | Location   |
   | ------------ | ---------- |
   | x.x.x.x/24   | OFFICE     |
   | x.x.x.x/24   | DATACENTER |
   | x.x.x.x/25   | DATACENTER |
   | x.x.x.x/26   | DATACENTER |

And the csv continues on, I want to create a new csv file from this that would expand the CIDR to all its possible IPs, but still have the proper location tied to it.

  | IPs       | Location |
  | --------  | -------  |
  | y.y.y.y   | OFFICE   |
  | y.y.y.y   | OFFICE   |
  | y.y.y.y   | OFFICE   |
  | y.y.y.y   | OFFICE   |
  | y.y.y.y   | OFFICE   |

and so on

CodePudding user response:

One way of doing it is using netaddr module & apply to CIDR column

>>> import netaddr
>>> data = {
    'CIDR': ['10.0.0.0/29', '10.1.2.0/30',  '192.168.1.0/29', '172.16.0.0/29'],
    'Location': [  'OFFICE',  'DATACENTER',  'DATACENTER', 'DATACENTER']}
>>> df = pd.DataFrame(data)
>>> pd.concat([df,df.CIDR.apply(netaddr.IPNetwork).explode().rename('IP')], axis=1)


    CIDR            Location    IP
0   10.0.0.0/29     OFFICE      10.0.0.0
0   10.0.0.0/29     OFFICE      10.0.0.1
0   10.0.0.0/29     OFFICE      10.0.0.2
0   10.0.0.0/29     OFFICE      10.0.0.3
0   10.0.0.0/29     OFFICE      10.0.0.4
0   10.0.0.0/29     OFFICE      10.0.0.5
0   10.0.0.0/29     OFFICE      10.0.0.6
0   10.0.0.0/29     OFFICE      10.0.0.7
1   10.1.2.0/30     DATACENTER  10.1.2.0
1   10.1.2.0/30     DATACENTER  10.1.2.1
1   10.1.2.0/30     DATACENTER  10.1.2.2
1   10.1.2.0/30     DATACENTER  10.1.2.3
2   192.168.1.0/29  DATACENTER  192.168.1.0
2   192.168.1.0/29  DATACENTER  192.168.1.1
2   192.168.1.0/29  DATACENTER  192.168.1.2
2   192.168.1.0/29  DATACENTER  192.168.1.3
2   192.168.1.0/29  DATACENTER  192.168.1.4
2   192.168.1.0/29  DATACENTER  192.168.1.5
2   192.168.1.0/29  DATACENTER  192.168.1.6
2   192.168.1.0/29  DATACENTER  192.168.1.7
3   172.16.0.0/29   DATACENTER  172.16.0.0
3   172.16.0.0/29   DATACENTER  172.16.0.1
3   172.16.0.0/29   DATACENTER  172.16.0.2
3   172.16.0.0/29   DATACENTER  172.16.0.3
3   172.16.0.0/29   DATACENTER  172.16.0.4
3   172.16.0.0/29   DATACENTER  172.16.0.5
3   172.16.0.0/29   DATACENTER  172.16.0.6
3   172.16.0.0/29   DATACENTER  172.16.0.7


CodePudding user response:

Assuming your DataFrame has valid CIDR you can combine ipaddress.IPv4Network and pandas.DataFrame.explode:

import ipaddress
df2 = (df.assign(CIDR=df['CIDR'].map(lambda x: list(ipaddress.IPv4Network(x))))
         .explode('CIDR')
      )

example input:

df = pd.DataFrame({'CIDR': ['192.168.1.0/24', '10.0.0.0/24'],
                   'Location': ['OFFICE', 'DATACENTER']})

output:

           CIDR    Location
0   192.168.1.0      OFFICE
0   192.168.1.1      OFFICE
0   192.168.1.2      OFFICE
0   192.168.1.3      OFFICE
0   192.168.1.4      OFFICE
..          ...         ...
1    10.0.0.251  DATACENTER
1    10.0.0.252  DATACENTER
1    10.0.0.253  DATACENTER
1    10.0.0.254  DATACENTER
1    10.0.0.255  DATACENTER

[512 rows x 2 columns]
  • Related