讲师中心 微信公众号
AI工具推荐 视频效率加速

如何高效判断端口号集合是否存在交集

雨浩姑娘_6867

雨浩姑娘_6867

发布时间:2026-01-31 11:42:33

|

723人浏览过

|

来源于php中文网

原创

如何高效判断端口号集合是否存在交集

本文介绍在防火墙访问控制列表(acl)分析场景下,快速检测目标端口范围是否与已有服务端口范围存在交集的三种算法方案,并重点推荐基于区间排序与二分查找的最优实践。

在网络安全运维与自动化策略分析中,常需判断一组待检端口(如 {"5672", "15672-15674"})是否与防火墙 ACL 中已配置的服务端口范围(如 {"20-22", "443", "8080-8088", "10000-65535"})存在交集。由于端口表示形式混合了单值(443)与区间(20-22),直接暴力展开为完整整数集合(如 {20,21,22})虽逻辑清晰,但在端口范围广(如 10000-65535 含 55536 个端口)时极易引发内存与性能瓶颈。因此,需设计不展开、低开销、可复用的区间交集判定方案。

✅ 推荐方案:区间归一化 + 有序范围二分查找(Approach 2)

该方案将所有端口统一为 [start, end] 形式(如 "443" → (443, 443),"20-22" → (20, 22)),对 ACL 区间列表按 start 排序后构建 List<PortRange>,再对每个待查区间,利用二分查找快速定位潜在重叠候选,最后精确判断区间是否相交。

网络安全新闻持序迭代
网络安全新闻持序迭代

提供基于权威源的国内外网络安全新闻查询,涵盖公司动态、事件、漏洞、政策、产品及AI应用,按报道数量排序展示。

下载
public record PortRange(int start, int end) {
    public boolean intersects(PortRange other) {
        return this.start <= other.end && other.start <= this.end;
    }
}

public class PortRangeChecker {
    private final List<PortRange> sortedAclRanges;

    public PortRangeChecker(String[] aclPortStrings) {
        this.sortedAclRanges = Arrays.stream(aclPortStrings)
                .map(PortRangeChecker::parseRange)
                .sorted(Comparator.comparingInt(PortRange::start))
                .collect(Collectors.toList());
    }

    private static PortRange parseRange(String s) {
        String[] parts = s.trim().split("-");
        int start = Integer.parseInt(parts[0]);
        int end = parts.length == 2 ? Integer.parseInt(parts[1]) : start;
        return new PortRange(Math.min(start, end), Math.max(start, end));
    }

    public boolean hasIntersection(String[] targetPortStrings) {
        for (String target : targetPortStrings) {
            PortRange targetRange = parseRange(target);
            // 二分查找首个 start <= targetRange.end 的区间(潜在重叠起点)
            int pos = binarySearchFirstStartLE(sortedAclRanges, targetRange.end);
            if (pos < 0) continue;
            // 向前/向后有限扫描(通常只需检查 1~2 个邻近区间)
            for (int i = Math.max(0, pos - 1); i < Math.min(sortedAclRanges.size(), pos + 2); i++) {
                if (sortedAclRanges.get(i).intersects(targetRange)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static int binarySearchFirstStartLE(List<PortRange> list, int upperBound) {
        int left = 0, right = list.size();
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (list.get(mid).start() <= upperBound) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left - 1; // 最右满足 start <= upperBound 的索引
    }
}

优势总结:

  • 时间复杂度优: 预处理 ACL 一次为 O(n log n);每次查询为 O(m log n)(n = ACL 区间数,m = 待查区间数),远优于暴力展开的 O(a + s) 内存与潜在 O(a × s) 比较;
  • 内存友好: 仅存储区间端点,空间复杂度稳定为 O(n + m);
  • 工程友好: 支持 ACL 列表预构建、多轮复用,契合实际防火墙策略批量校验场景。

⚠️ 其他方案对比说明

  • 方案 1(全量端口 Set): 适用于极小 ACL(如 < 100 个端口)且查询极少的场景。一旦出现 10000-65535 类宽区间,内存占用飙升至数万整数,且无法复用计算结果,不推荐用于生产环境。
  • 方案 3(事件点扫描法): 将所有区间的起止点合并排序并标记类型(+1 起始 / -1 结束),通过扫描计数判断覆盖。虽理论简洁,但实现稍繁,且每次查询均需重建合并序列,时间复杂度 O((n+m) log(n+m)) 略逊于方案 2,实用性较低。

✅ 实践建议

  • 始终对 ACL 端口字符串做合法性校验与归一化(如自动交换 65535-10000 为 10000-65535);
  • 若 ACL 极大(n > 10⁴)且查询高频,可进一步升级为 TreeSet<PortRange> 并自定义比较器,或采用线段树(Segment Tree)优化最坏查询性能;
  • 在日志或告警中明确输出首次命中交集的具体区间对(如 "15672-15674 overlaps with 10000-65535"),提升排障效率。

综上,区间归一化 + 有序列表 + 二分定位 + 局部扫描是平衡开发成本、运行效率与资源消耗的最佳路径,适用于绝大多数企业级防火墙策略分析系统。

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1758

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2744

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6104

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5769

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

7414

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

10894

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

5579

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

6087

2025.08.07

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Linux网络安全之防火墙技术汇总
Linux网络安全之防火墙技术汇总

共31课时 | 4.2万人学习

uni-app从入门到实战教程
uni-app从入门到实战教程

共0课时 | 0人学习

uni-app x harmony开发指南
uni-app x harmony开发指南

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn