Cidr4 merge algorithm #5
+37
-20
@@ -37,37 +37,41 @@ def reduce_binary(binary: str) -> str:
|
|||||||
return binary[:vlsm] + "0" + binary[vlsm + 1 :]
|
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]:
|
def rough_merge_binaries(binaries: List[str], req_len: int) -> List[str]:
|
||||||
ips = set(deepcopy(binaries))
|
ips = set(deepcopy(binaries))
|
||||||
non_reducible_ips = set()
|
|
||||||
reduction_limit_reached = False
|
reduction_limit_reached = False
|
||||||
max_vlsm = float("inf")
|
max_vlsm = float("inf")
|
||||||
while (
|
while len(ips) > req_len and not reduction_limit_reached and max_vlsm != -1:
|
||||||
len(ips) > 0
|
|
||||||
and len(ips) + len(non_reducible_ips) > req_len
|
|
||||||
and not reduction_limit_reached
|
|
||||||
and max_vlsm != -1
|
|
||||||
):
|
|
||||||
ip_with_max_vlsm = max(ips, key=lambda x: x.rfind("1"))
|
ip_with_max_vlsm = max(ips, key=lambda x: x.rfind("1"))
|
||||||
max_vlsm = ip_with_max_vlsm.rfind("1")
|
max_vlsm = ip_with_max_vlsm.rfind("1")
|
||||||
reduced_ips = set()
|
reduced_ips = set()
|
||||||
merged_ips = set()
|
merged_ips = set()
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
if ip.rfind("1") == max_vlsm:
|
if ip.rfind("1") == max_vlsm:
|
||||||
reduced_ip = reduce_binary(ip)
|
reduced_ips.add(reduce_binary(ip))
|
||||||
if "1" in reduced_ip:
|
|
||||||
reduced_ips.add(reduced_ip)
|
|
||||||
else:
|
|
||||||
non_reducible_ips.add(ip)
|
|
||||||
else:
|
else:
|
||||||
merged_ips.add(ip)
|
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)
|
merged_ips.update(reduced_ips)
|
||||||
if len(merged_ips) + len(non_reducible_ips) > req_len:
|
|
||||||
|
if len(merged_ips) > req_len:
|
||||||
ips = merged_ips
|
ips = merged_ips
|
||||||
else:
|
else:
|
||||||
reduction_limit_reached = True
|
reduction_limit_reached = True
|
||||||
|
|
||||||
ips.update(non_reducible_ips)
|
|
||||||
return sorted(ips)
|
return sorted(ips)
|
||||||
|
|
||||||
|
|
||||||
@@ -81,7 +85,7 @@ def smooth_merge_binaries(binaries: List[str], req_len: int) -> List[str]:
|
|||||||
ips.add(ip)
|
ips.add(ip)
|
||||||
|
|
||||||
while len(ips) > 0 and len(ips) + len(non_reducible_ips) > req_len:
|
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)
|
group_dict = defaultdict(list)
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
@@ -120,18 +124,26 @@ def main():
|
|||||||
|
|
||||||
data = get_data(file)
|
data = get_data(file)
|
||||||
bin_ips = list(map(cidr4_to_binary, data))
|
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)
|
rough_merged_bin_ips = rough_merge_binaries(bin_ips, required_len)
|
||||||
print(f"{len(rough_merged_bin_ips)=}")
|
print(f"{len(rough_merged_bin_ips)=}")
|
||||||
for ip in rough_merged_bin_ips:
|
for ip in rough_merged_bin_ips:
|
||||||
print(ip)
|
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)
|
# smooth_merged_bin_ips = smooth_merge_binaries(bin_ips, required_len)
|
||||||
print(f"{len(smooth_merged_bin_ips)=}")
|
# print(f"{len(smooth_merged_bin_ips)=}")
|
||||||
for ip in smooth_merged_bin_ips:
|
# for ip in smooth_merged_bin_ips:
|
||||||
print(ip)
|
# print(ip)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@@ -153,5 +165,10 @@ if __name__ == "__main__":
|
|||||||
assert reduce_binary("0" * 32) == "0" * 32
|
assert reduce_binary("0" * 32) == "0" * 32
|
||||||
assert reduce_binary("00000000000010000000000000000000") == "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()
|
main()
|
||||||
# cProfile.run("main()")
|
# cProfile.run("main()")
|
||||||
|
|||||||
Reference in New Issue
Block a user