RosettaCodeData/Task/Canonicalize-CIDR/Python/canonicalize-cidr-1.py

29 lines
1.1 KiB
Python

#!/usr/bin/env python
# canonicalize a CIDR block specification:
# make sure none of the host bits are set
import sys
from socket import inet_aton, inet_ntoa
from struct import pack, unpack
args = sys.argv[1:]
if len(args) == 0:
args = sys.stdin.readlines()
for cidr in args:
# IP in dotted-decimal / bits in network part
dotted, size_str = cidr.split('/')
size = int(size_str)
numeric = unpack('!I', inet_aton(dotted))[0] # IP as an integer
binary = f'{numeric:#034b}' # then as a padded binary string
prefix = binary[:size + 2] # just the network part
# (34 and +2 are to account
# for leading '0b')
canon_binary = prefix + '0' * (32 - size) # replace host part with all zeroes
canon_numeric = int(canon_binary, 2) # convert back to integer
canon_dotted = inet_ntoa(pack('!I',
(canon_numeric))) # and then to dotted-decimal
print(f'{canon_dotted}/{size}') # output result