27

How can I get a CIDR notation representing a range of IP addresses, given the start and end IP addresses of the range, in Python? I can find CIDR to IP Range but cannot find any code for the reverse.

Example of the desired output:

startip = '63.223.64.0'
endip = '63.223.127.255'

return '63.223.64.0/18'
stkent
  • 19,772
  • 14
  • 85
  • 111
Chris Hall
  • 871
  • 6
  • 13
  • 21

3 Answers3

37

Starting Python 3.3 the bundled ipaddress can provide what you want. The function summarize_address_range returns an iterator with the networks resulting from the start, end you specify:

>>> import ipaddress
>>> startip = ipaddress.IPv4Address('63.223.64.0')
>>> endip = ipaddress.IPv4Address('63.223.127.255')
>>> [ipaddr for ipaddr in ipaddress.summarize_address_range(startip, endip)]
[IPv4Network('63.223.64.0/18')]
Jason
  • 9,408
  • 5
  • 36
  • 36
MichielB
  • 4,181
  • 1
  • 30
  • 39
25

You may use iprange_to_cidrs provided by netaddr module. Example:

pip install netaddr
import netaddr
cidrs = netaddr.iprange_to_cidrs(startip, endip)

Here are the official docs: https://netaddr.readthedocs.io/

Jason
  • 9,408
  • 5
  • 36
  • 36
ρss
  • 5,115
  • 8
  • 43
  • 73
  • cidrs = netaddr.ip_range_to_cidrs(ip1 , ip2 ) AttributeError: 'module' object has no attribute 'ip_range_to_cidrs' – Chris Hall Jun 13 '14 at 22:31
  • 1
    @ChrisHall Sorry for the typo, I have updated my answer. – ρss Jun 14 '14 at 11:46
  • 2
    Here's how to do it in Python3: from ipaddress import ip_address, summarize_address_range; start,end = ip_address(startip), ip_address(endip); return summarize_address_range(start,end). – JJC Mar 09 '16 at 15:55
  • 2
    To tidy up @JJC's answer for `python 2.7`................................................................................................. ```from ipaddress import ip_address,summarize_address_range; summarize_address_range(ip_address(unicode(startip)), ip_address(unicode(endip)))``` – Alexander McFarlane Oct 30 '16 at 18:38
0

If, like me, you want only 1 cidr (instead of multiple cidr's) you'll need to use the spanning_cidr function from either netaddr

pip install netaddr

from netaddr import spanning_cidr
spanning_cidr(startip, endip)

or spanning_cidr

pip install spanning-cidr

from spanning_cidr import spanning_cidr
spanning_cidr([startip, endip])

Here is the difference...

>>> from ipaddress import IPv4Address, summarize_address_range
>>> from netaddr import spanning_cidr
>>>
>>> startip = IPv4Address('63.223.64.0')
>>> endip = IPv4Address('63.224.127.255')
>>> list(summarize_address_range(startip, endip))
[IPv4Network('63.223.64.0/18'),
 IPv4Network('63.223.128.0/17'),
 IPv4Network('63.224.0.0/17')]
>>>
>>> spanning_cidr(startip, endip)
IPv4Network('63.192.0.0/10')
reubano
  • 5,087
  • 1
  • 42
  • 41