diff --git a/tests/cidr4_merge/test_cidr4_merger.py b/tests/cidr4_merge/test_cidr4_merger.py index 319976b..32add5f 100644 --- a/tests/cidr4_merge/test_cidr4_merger.py +++ b/tests/cidr4_merge/test_cidr4_merger.py @@ -6,6 +6,7 @@ from vpn_manager.cidr4_merge.cidr4_merger import ( cidr4_to_node, find_parent, make_cidr4, + merge_two_nodes, sort_nodes, ) @@ -88,13 +89,20 @@ def test_find_parent__with_exception(): def test_calc_dip(): + assert calc_dip(32, 32) == 0 + assert calc_dip(32, 31) == 2 + assert calc_dip(32, 30) == 4 + assert calc_dip(31, 30) == 2 + assert calc_dip(30, 29) == 4 + assert calc_dip(29, 31) == 6 assert calc_dip(26, 26) == 0 + assert calc_dip(3, 2) == 2**30 - 2**29 + assert calc_dip(3, 1) == 2**31 - 2**29 - assert calc_dip(26, 27) == 67108864 - assert calc_dip(27, 26) == 67108864 - assert calc_dip(26, 28) == 201326592 - assert calc_dip(28, 26) == 201326592 - - assert calc_dip(26, 29) == 469762048 - assert calc_dip(29, 26) == 469762048 +def test_merge_two_nodes(): + assert merge_two_nodes((0, 32), (1, 32)) == ((0, 31), 0) + assert merge_two_nodes((0, 32), (2, 32)) == ((0, 30), 4) + assert merge_two_nodes((0, 32), (5, 32)) == ((0, 29), 8) + assert merge_two_nodes((3, 32), (4, 32)) == ((0, 29), 8) + assert merge_two_nodes((0, 32), (4, 30)) == ((0, 29), 4) diff --git a/vpn_manager/cidr4_merge/cidr4_merger.py b/vpn_manager/cidr4_merge/cidr4_merger.py index a2d7802..c3bfeab 100644 --- a/vpn_manager/cidr4_merge/cidr4_merger.py +++ b/vpn_manager/cidr4_merge/cidr4_merger.py @@ -43,14 +43,25 @@ def find_parent(a: Node, b: Node) -> Node: def calc_dip(mask_len_a: int, mask_len_b: int) -> int: - dip = 0 - len_min, len_max = sorted((mask_len_a, mask_len_b)) - while len_min < len_max: - dip += 1 << len_min - len_min += 1 + # a = 2 ** (32 - mask_len_a) if mask_len_a != 32 else 0 + # b = 2 ** (32 - mask_len_b) if mask_len_b != 32 else 0 + a = 1 << (32 - mask_len_a) if mask_len_a != 32 else 0 + b = 1 << (32 - mask_len_b) if mask_len_b != 32 else 0 + dip = abs(a - b) return dip +def merge_two_nodes(node_a: Node, node_b: Node) -> tuple[Node, int]: + ip_a, mask_len_a = node_a + ip_b, mask_len_b = node_b + parent_node = find_parent(node_a, node_b) + _, mask_len_p = parent_node + dip_a = calc_dip(mask_len_a, mask_len_p + 1) + dip_b = calc_dip(mask_len_b, mask_len_p + 1) + dip = dip_a + dip_b + return parent_node, dip + + def make_cidr4(ip, mask_len) -> str: lst = [str(ip >> (i << 3) & 0xFF) for i in reversed(range(4))] ip_address = ".".join(lst)