6

How can I convert a CIDR prefix to a dotted-quad netmask in Python?

For example, if the prefix is 12 I need to return 255.240.0.0.

planetp
  • 14,248
  • 20
  • 86
  • 160

4 Answers4

13

Here is a solution on the lighter side (no module dependencies):

netmask = '.'.join([str((0xffffffff << (32 - len) >> i) & 0xff)
                    for i in [24, 16, 8, 0]])
planetp
  • 14,248
  • 20
  • 86
  • 160
Curt
  • 470
  • 3
  • 7
6

You can do it like this:

def cidr(prefix):
    return socket.inet_ntoa(struct.pack(">I", (0xffffffff << (32 - prefix)) & 0xffffffff))
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
1

And this is a more efficient one:

netmask = 0xFFFFFFFF & (2**(32-len)-1)

or, if you have difficulties counting the number of F:

netmask = (2**32-1) & ~ (2 ** (32-len)-1)

and now a possibly even more efficient (albeit more difficult to read):

netmask = (1<<32)-1 & ~ ((1 << (32-len))-1)

To get the dotted.quad version of the mask, you can use inet.ntoa to convert the above netmask.
Note: for uniformity with other message, I used 'len' as the mask length, even if I do not like to use a function name as variable name.

user3435121
  • 633
  • 4
  • 13
0

Yet another way to do it

>> cidr=22
>> netmask = '.'.join([str((m>>(3-i)*8)&0xff) for i,m in enumerate([-1<<(32-cidr)]*4)])
>> print(netmask)
'255.255.252.0'
kriss
  • 23,497
  • 17
  • 97
  • 116