Skip to content

Instantly share code, notes, and snippets.

@aji
Created October 1, 2012 20:28
Show Gist options
  • Select an option

  • Save aji/3814226 to your computer and use it in GitHub Desktop.

Select an option

Save aji/3814226 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import sys
def usage(argv0):
print('Usage: {} FILE [FILE ...]'.format(argv0))
print('')
print('FILE can be - to mean standard input. Files are concatenated together')
print('and read in the order specified. Files should contain a list of IPv4')
print('addresses, one on each line.')
def parse_addr(line):
chunks = line.split('.')
if len(chunks) != 4:
return None
addr = 0
for digit in [int(x) for x in chunks]:
addr = addr * 256 + digit
return addr
def read_addrs(f):
addrs = []
for line in f:
addr = parse_addr(line)
if addr is not None:
addrs.append(addr)
return addrs
def read_all(fnames):
addrs = set([])
for fname in fnames:
if fname == '-':
f = sys.stdin
else:
try:
f = open(fname, 'r')
except IOError:
print('Error opening {}, skipping'.format(fname))
continue
addrs = addrs | set(read_addrs(f))
return addrs
def find_mask(a, b):
n = a ^ b
for i in range(5):
n = n | (n >> (1 >> i))
return ~n
def format_ip(addr):
digits = []
for i in range(4):
addr, digit = divmod(addr, 256)
digits[:0] = [str(digit)]
return '.'.join(digits)
def format_cidr(addr, mask):
i = 0
while (mask & (1<<i)) == 0:
i = i + 1
return format_ip(addr) + '/' + str(32-i)
def main(argv):
if len(argv) < 2:
usage(argv[0])
return 1
addrs = read_all(argv[1:])
low = min(addrs)
hi = max(addrs)
mask = find_mask(low, hi)
print(format_cidr(low&mask, mask))
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment