wikimedia / ip-set
高效匹配IP地址与一系列CIDR规范。
Requires (Dev)
- mediawiki/mediawiki-codesniffer: 41.0.0
- mediawiki/mediawiki-phan-config: 0.12.1
- mediawiki/minus-x: 1.1.1
- ockcyp/covers-validator: 1.6.0
- php-parallel-lint/php-console-highlighter: 1.0.0
- php-parallel-lint/php-parallel-lint: 1.3.2
- phpunit/phpunit: 9.5.28
README
IPSet是一个用于匹配IP地址与一系列CIDR规范的PHP库。
以下是使用方法
use Wikimedia\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规范相比,速度提升了100多倍。
基本实现是两个独立的二叉树(IPv4和IPv6),作为嵌套的PHP数组,键名为0和1。false和true是匹配失败和匹配成功的终端匹配,否则值是树中的更深层次的节点。
还实现了简单的深度压缩方案:仅在整字节边界上进行整字节树压缩,在那个整字节的深度中没有分支发生。压缩节点有'comp'(比较的字节)和'next'(如果'comp'匹配成功,则递归到下一个节点)键。
例如,给定以下输入
25.0.0.0/9 25.192.0.0/10
IPv4树将看起来像
root4 => [ 'comp' => 25, 'next' => [ 0 => true, 1 => [ 0 => false, 1 => true, ], ], ];
(也尝试了多字节压缩节点,但在我的测试场景中由于额外的匹配复杂性,结果是净损失)
许可证
版权所有 2014, 2015 Brandon Black blblack@gmail.com
此程序是自由软件;您可以在自由软件基金会发布的GNU通用公共许可证的条款下重新分发和/或修改它;许可证版本2,或(根据您的选择)许可证的任何后续版本。
此程序是在希望它将是有用的前提下分发的,但没有任何保证;甚至没有关于适销性或适用于特定目的的暗示性保证。有关详细信息,请参阅GNU通用公共许可证。
您应该已随此程序收到GNU通用公共许可证副本;如果没有,请写信给自由软件基金会,Inc.,51 Franklin Street,第五层,波士顿,MA 02110-1301,美国。 https://gnu.ac.cn/copyleft/gpl.html