Created
October 1, 2012 20:28
-
-
Save aji/3814226 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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