Welcome, guest | Sign In | My Account | Store | Cart

How to convert the CIDR notation (192.168.0.0/24) of a subnetmask to the dotted decimal form (255.255.255.0).

Python, 20 lines
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20``` ```#!/usr/bin/env python import sys def usage(): print "Call : %s " % sys.argv print " shows the dotted netmask (i.e %s 24 => 255.255.255.0)" % sys.argv def calcDottedNetmask(mask): bits = 0 for i in xrange(32-mask,32): bits |= (1 << i) return "%d.%d.%d.%d" % ((bits & 0xff000000) >> 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff)) if __name__ == "__main__": if len(sys.argv) > 1 and sys.argv.isdigit(): print calcDottedNetmask(int(sys.argv)) else: usage() ``` David Moss 13 years, 3 months ago

Actually, the following drops the looping construct and is over 4x faster!

``````from socket import inet_ntoa
from struct import pack

...

bits = 0xffffffff ^ (1 << 32 - mask) - 1
return inet_ntoa(pack('>I', bits))
`````` David Moss 13 years, 3 months ago

Nice bit of logic which I'll likely add to the netaddr project in due course ;-)

I would change the return statement slightly to improve readability (and save some typing).

``````from socket import inet_ntoa
from struct import pack

...

bits = 0
bits |= (1 << i)
return inet_ntoa(pack('>I', bits))

...
``````

Also, a range check for the `mask` argument might be a good idea as the `calcDottedNetmask()` function currently accepts negative values such as `-1`, albeit returning a 'safe' `0.0.0.0`, which should probably more correctly raise an error.

Dave M. Humberto Diógenes 8 years, 2 months ago

Or, if you want the opposite:

``````>>> sum([bin(int(x)).count('1') for x in '255.255.255.0'.split('.')])
30
`````` Created by gerontosepp on Wed, 3 Sep 2008 (MIT)