om3rcitak / ip-set
高效地将IP地址与一组CIDR规范进行匹配。
Requires
- php: >=7.2.9
- wikimedia/at-ease: ^2.0.0
Requires (Dev)
- mediawiki/mediawiki-codesniffer: 38.0.0
- mediawiki/mediawiki-phan-config: 0.11.0
- mediawiki/minus-x: 1.1.1
- ockcyp/covers-validator: 1.3.3
- php-parallel-lint/php-console-highlighter: 0.5.0
- php-parallel-lint/php-parallel-lint: 1.3.1
- phpunit/phpunit: ^8.5
README
注意:此项目是从 Wikimedia/IPSet 分支出来的。
IPSet 是一个用于将IP地址与一组CIDR规范进行匹配的PHP库。
以下是使用方法
use Om3rcitak\IPSet; // At startup, calculate the optimized data structure for the set: $ipset = new IPSet( [ '208.80.154.0/26', '2620:0:861:1::/64', '10.64.0.0/22', ] ); // Runtime check against cached set (returns bool): if ( $ipset->match( $ip ) ) { // ... }
在粗略基准测试中,这比在短数组(最多几百个)上使用 in_array()
检查花费了大约 80% 的时间。然而,在这些级别上,它仍然很快,如果数组很大,IPSet 的扩展性会比 in_array 更好。
然而,对于混合家族的CIDR集合,这段代码比在CIDR规范数组上迭代 Wikimedia\IPUtils::isInRange()
快了100多倍。
基本实现是两个独立的二叉树(IPv4和IPv6),作为嵌套的PHP数组,键名为0和1。false和true是终端匹配失败和匹配成功的值,否则值是树中的更深节点。
还实现了一个简单的深度压缩方案:仅在整字节边界处进行整字节树压缩,在该整字节深度中不会发生分支。压缩节点有键 'comp'(要比较的字节)和 'next'(如果 'comp' 成功匹配,则递归到下一个节点的下一个节点)。
例如,给定以下输入
25.0.0.0/9 25.192.0.0/10
v4树将看起来像
root4 => [ 'comp' => 25, 'next' => [ 0 => true, 1 => [ 0 => false, 1 => true, ], ], ];
(也尝试了多字节压缩节点,但在我的测试场景中由于额外的匹配复杂性,结果是净损失)
许可证
版权所有 2014, 2015 Brandon Black blblack@gmail.com
此程序是免费软件;您可以在自由软件基金会发布的GNU通用公共许可证的条款和条件下重新分发和/或修改它;许可证的第2版,或(根据您的选择)许可证的任何后续版本。
此程序的分发是希望它将是有用的,但没有任何保证;甚至没有关于适销性或特定目的适用性的暗示保证。有关详细信息,请参阅GNU通用公共许可证。
您应该已经随此程序收到了GNU通用公共许可证的副本;如果没有,请写信给自由软件基金会,51 Franklin Street,第五层,波士顿,MA 02110-1301,USA。 https://gnu.ac.cn/copyleft/gpl.html