#range #cidr #set #merge #applications #overlapping #adjacent

无std libnetrangemerge

实现了一个算法,该算法用于合并重叠和相邻的网络范围,以创建一个覆盖整体网络相同部分的最小范围值集合

1个不稳定版本

0.1.0 2021年4月10日

#4 in #adjacent


netrange 中使用

MIT/Apache

54KB
868 代码行,不包括注释

libnetrangemerge

libnetrangemerge 实现了一个算法,该算法接收一系列 CIDR 网络范围,并生成一个最小输出CIDR范围集合,其中所有重叠和相邻的范围都已合并。

给定CIDR范围列表 0.0.0.0/0127.0.0.0/8,libnetrangemerge 将生成输出CIDR范围 0.0.0.0/0,因为这个范围完全覆盖了第二个范围。

考虑到CIDR范围列表 127.0.00/25127.0.0128/25,libnetrangemerge将生成输出CIDR范围 127.0.00/24,因为这两个输入范围是相邻的。然而,并非所有相邻的范围都可以合并。例如,127.0.01/32127.0.02/32 虽然相邻,但由于无法用CIDR形式表示范围 127.0.01 - 127.0.02,所以不能合并。

CIDR范围合并并不是适用于所有操作CIDR范围的程序。如果程序希望根据特定范围做出不同的决策,将那些范围合并成更小的集合将没有用处。然而,对于将一系列范围同等对待的程序,将它们合并成最小集合是有用的。

范围选择

libnetrangemerge的每个输入CIDR范围都必须标记有selected标志。当两个范围合并时,如果任一输入范围被标记为selected,则输出范围也将被标记为selected;如果两个范围都没有标记,则输出范围也不会被标记。selected状态对合并没有其他影响。

此功能可以在某些特定情况下最小化范围。例如,如果程序想要获取Amazon EC2服务器使用的CIDR范围集合,它可以获取所有Amazon IP范围列表,过滤掉EC2不使用的所有内容,然后合并结果集。不幸的是,EC2范围可能不是彼此相邻的——中间可能有由其他Amazon服务使用的范围。如果程序想要创建尽可能小的范围集合,可能需要使用这些其他范围来填补EC2范围之间的空白。程序可以通过将每个Amazon范围传递给libnetrangemerge来完成此操作,但将EC2范围标记为selected而其他范围不标记。然后可以通过丢弃未标记为selected的输出范围来过滤输出集。在这种情况下,输出集将不再仅代表EC2范围——但如果程序可以接受这一点,这将导致输出集更小。

selected功能是可选的——如果程序不想使用它,程序只需将每个范围标记为selected或不标记,然后不从结果中过滤任何内容。

用法

CIDR 范围由一个实现 Range 特性的结构体表示。库中包含该特性的 3 个实现:IpRangeIpv4RangeIpv6Range。应用程序也可以为它们的自定义类型实现 Range 特性。

合并操作通过创建一个范围值列表,然后将该列表传递给 merge_rangesmerge_ranges_slice 来实现。这两个函数实现了相同的算法——区别在于前者期望一个 &mut Vec<Range>,它将就地合并并截断到输出集合的大小,而后者期望一个 &mut [Range],它将就地合并并返回输出集合的大小。当使用 merge_ranges_slice 时,应用程序的责任是不访问返回大小之后的任何范围——这样做是安全的,但会导致 panic。

merge_rangesmerge_ranges_slice 都是在原地操作,不分配内存,并且在假设 Range 类型的所有方法都不会 panic 的情况下,不会失败或 panic。

示例

use libnetrangemerge::{RangeInterest, IpRange, merge_ranges};

let mut ranges: Vec<RangeInterest<IpRange>> = vec![
   RangeInterest::new("127.0.0.8/29".parse().unwrap(), true),
   RangeInterest::new("127.0.0.16/29".parse().unwrap(), true),
   RangeInterest::new("0.0.0.0/0".parse().unwrap(), true),
];

merge_ranges(&mut ranges);

no_std 支持

libnetrangemerge 与 no_std 兼容。然而,在 no_std 模式下,merge_ranges 方法不可用,内置的范围类型也是如此。应用程序可以实现自己的类型,该类型实现了 Range 特性,并将该类型的实例传递给 merge_ranges_slice 以进行合并。

最小 Rust 版本策略

libnetrangemerge 是在 rustc 1.51 上开发的,并且可能也与更早的版本兼容。

最小支持的 rustc 版本可能会随着小版本更新而提高。

许可证

本项目根据您的选择,许可为以下之一

任选其一。

依赖项

~320–560KB
~15K SLoC