From 7d89eee92f18d21c728a7b2636d25eb7b437c32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB?= Date: Thu, 9 Jan 2025 01:09:29 +0300 Subject: [PATCH] =?UTF-8?q?fix=20rough=5Fmerge=5Fbinaries=20fun=D1=81,=20p?= =?UTF-8?q?reviously=20the=20function=20returned=20networks=20and=20subnet?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cidr4_merger.py | 57 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/cidr4_merger.py b/cidr4_merger.py index fbbebed..0626792 100644 --- a/cidr4_merger.py +++ b/cidr4_merger.py @@ -37,37 +37,41 @@ def reduce_binary(binary: str) -> str: return binary[:vlsm] + "0" + binary[vlsm + 1 :] +def get_mask(binary: str) -> str: + i = binary.rfind("1") + return binary[: i + 1] + + def rough_merge_binaries(binaries: List[str], req_len: int) -> List[str]: ips = set(deepcopy(binaries)) - non_reducible_ips = set() reduction_limit_reached = False max_vlsm = float("inf") - while ( - len(ips) > 0 - and len(ips) + len(non_reducible_ips) > req_len - and not reduction_limit_reached - and max_vlsm != -1 - ): + while len(ips) > req_len and not reduction_limit_reached and max_vlsm != -1: ip_with_max_vlsm = max(ips, key=lambda x: x.rfind("1")) max_vlsm = ip_with_max_vlsm.rfind("1") reduced_ips = set() merged_ips = set() for ip in ips: if ip.rfind("1") == max_vlsm: - reduced_ip = reduce_binary(ip) - if "1" in reduced_ip: - reduced_ips.add(reduced_ip) - else: - non_reducible_ips.add(ip) + reduced_ips.add(reduce_binary(ip)) else: merged_ips.add(ip) + + filtered_set = set() + for r_ip in reduced_ips: + mask = get_mask(r_ip) + for ip in merged_ips: + if ip.startswith(mask): + filtered_set.add(r_ip) + + reduced_ips -= filtered_set merged_ips.update(reduced_ips) - if len(merged_ips) + len(non_reducible_ips) > req_len: + + if len(merged_ips) > req_len: ips = merged_ips else: reduction_limit_reached = True - ips.update(non_reducible_ips) return sorted(ips) @@ -81,7 +85,7 @@ def smooth_merge_binaries(binaries: List[str], req_len: int) -> List[str]: ips.add(ip) while len(ips) > 0 and len(ips) + len(non_reducible_ips) > req_len: - print(f"{req_len=} {len(ips) + len(non_reducible_ips)=}") + # print(f"{req_len=} {len(ips) + len(non_reducible_ips)=}") group_dict = defaultdict(list) for ip in ips: @@ -120,18 +124,26 @@ def main(): data = get_data(file) bin_ips = list(map(cidr4_to_binary, data)) + # for ip in bin_ips: + # print(ip) + # print("#" * 128) rough_merged_bin_ips = rough_merge_binaries(bin_ips, required_len) print(f"{len(rough_merged_bin_ips)=}") for ip in rough_merged_bin_ips: print(ip) - print("#" * 128) + # print("#" * 128) + # + # smooth_merged_bin_ips = smooth_merge_binaries(rough_merged_bin_ips, required_len) + # print(f"{len(smooth_merged_bin_ips)=}") + # for ip in smooth_merged_bin_ips: + # print(ip) - smooth_merged_bin_ips = smooth_merge_binaries(rough_merged_bin_ips, required_len) - print(f"{len(smooth_merged_bin_ips)=}") - for ip in smooth_merged_bin_ips: - print(ip) + # smooth_merged_bin_ips = smooth_merge_binaries(bin_ips, required_len) + # print(f"{len(smooth_merged_bin_ips)=}") + # for ip in smooth_merged_bin_ips: + # print(ip) if __name__ == "__main__": @@ -153,5 +165,10 @@ if __name__ == "__main__": assert reduce_binary("0" * 32) == "0" * 32 assert reduce_binary("00000000000010000000000000000000") == "0" * 32 + assert get_mask("00000100010011101000101100000000") == "000001000100111010001011" + assert get_mask("10000000000000000000000000000000") == "1" + assert get_mask("00000000000000000000000000000000") == "" + assert get_mask("00000000000010000000000000000000") == "0000000000001" + main() # cProfile.run("main()")