#!/bin/python import ipaddress import sys import argparse parser = argparse.ArgumentParser() parser.add_argument('-t', '--test', action='store_const', const=True, help='Тестовый режим') parser.add_argument('-s', '--summask', type=int, help='Суммаризация по маске') args = parser.parse_args() def read_ips(): ip_cnt,prefixes = 0, {} for line in sys.stdin: line, ip_cnt = line.strip('\n'), ip_cnt + 1 try: if ipaddress.ip_network(line) or ipaddress.ip_address(line): prefix = ipaddress.ip_network(line).network_address.compressed prefixlen = ipaddress.ip_network(line).prefixlen if args.summask and prefixlen > args.summask: supernet = ipaddress.ip_network(prefix,prefixlen).supernet(new_prefix=args.summask) prefix = supernet.network_address.compressed prefixlen = supernet.prefixlen prefixes[prefix] = prefixlen except ValueError: continue #bad subnet address if args.test: print('{} IP/Net -> stdin'.format(ip_cnt)) return prefixes def subnets_join(prefixes, new_prefixlen): new_prefixes = {} for network_address, prefixlen in prefixes.items(): if prefixlen == new_prefixlen + 1: supernet = ipaddress.ip_network(network_address, prefixlen).supernet(new_prefix=new_prefixlen) new_network_address = supernet.network_address.compressed subnets = list(supernet.subnets()) prefix_count = 0 for subnet in subnets: if prefixes.get(subnet.network_address.compressed) == subnet.prefixlen: prefix_count += 1 if prefix_count > 1: new_prefixes[new_network_address] = new_prefixlen else: new_prefixes[network_address] = prefixlen else: new_prefixes[network_address] = prefixlen return new_prefixes prefixes = read_ips() maxprefixlen,start_cnt = 32, len(prefixes) for prefixlen in range(maxprefixlen, 0, -1): prefixes = subnets_join(prefixes, prefixlen) if args.test: print('/{} - {} - {}%'.format(prefixlen, len(prefixes), int(100 / start_cnt * len(prefixes)))) if not args.test: [print('{}/{}'.format(pref, preflen)) for pref, preflen in prefixes.items()]