yabowarcherio/portspec
GitHub: yabowarcherio/portspec
一个纯逻辑的 TCP/UDP 端口规范解析与操作库及 CLI 工具,支持 nmap 风格端口表达式和集合运算。
Stars: 0 | Forks: 0
# portspec
[](https://github.com/yabowarcherio/portspec/actions/workflows/ci.yml)
[](#license)
解析和操作 TCP/UDP **端口规范** —— 以逗号分隔的端口和范围列表,
类似于 `nmap -p` (`"22,80,443,1000-2000"`) 中的形式。
基于 `u16` 端口号的纯整数逻辑:没有 socket,没有 DNS,没有嵌入的
数据。同时提供库 **和** CLI。
- **范围** —— `1000-2000`,支持开放式形式 `1024-`, `-1024`, `-`
- **规范** —— `22,80,443,8000-8002`,保持标准化(排序、合并、去重)
- 包含关系、计数、并集和交集
- 对覆盖端口的前向/反向迭代
## 安装
```
cargo install portspec # CLI
cargo add portspec # library
```
对于不需要 CLI 栈的仅库精简依赖:
```
[dependencies]
portspec = { version = "0.1", default-features = false }
```
## 使用方法 (CLI)
```
portspec [OPTIONS] ...
Arguments:
... Port specs to combine (union). Use `-` to read from stdin.
Options:
-c, --count Print the number of ports instead of listing them
-r, --ranges Print the normalized range form (e.g. 1-20,443)
--intersect Keep only ports also present in this spec
--contains Exit 0 if PORT is covered, 1 otherwise
-l, --limit Stop after listing N ports (0 = no limit)
-R, --reverse List ports from highest to lowest
-h, --help Print help
-V, --version
```
```
$ portspec 22,80,8000-8002
22
80
8000
8001
8002
$ portspec --ranges 80,1-10,11-20,80 # normalize + merge
1-20,80
$ portspec --count 1-1024 # 1024
$ portspec --intersect 50-150 --ranges 1-100 # 50-100
$ portspec --contains 443 1-1024 && echo open
```
**退出码:** `0` 成功 · `1` `--contains` 未匹配 · `2` 规范解析
失败。
## 使用方法 (库)
```
use portspec::PortSpec;
let spec: PortSpec = "22,80,443,8000-8002".parse().unwrap();
assert_eq!(spec.count(), 6);
assert!(spec.contains(8001));
// Normalized, merged, deduped — equal specs compare equal.
let a: PortSpec = "1-10,11-20,5-15".parse().unwrap();
assert_eq!(a.to_string(), "1-20");
// Set algebra.
let b: PortSpec = "15-30".parse().unwrap();
assert_eq!(a.union(&b).to_string(), "1-30");
assert_eq!(a.intersection(&b).to_string(), "15-20");
```
更多集合代数和转换:
```
use portspec::{PortRange, PortSpec};
let spec: PortSpec = "1-100".parse().unwrap();
// Difference, complement, and predicates.
assert_eq!(spec.difference(&"20-30".parse().unwrap()).to_string(), "1-19,31-100");
assert!(spec.is_subset_of(&"1-200".parse().unwrap()));
assert!(spec.complement().contains(0) && !spec.complement().contains(50));
// Build from individual ports (adjacent ones merge) and the IANA ranges.
assert_eq!(PortSpec::from_ports([80, 81, 82]).to_string(), "80-82");
assert_eq!(PortRange::WELL_KNOWN.to_string(), "0-1023");
```
`PortRange` 类型提供了单范围的操作接口(解析、`contains`、
`overlaps`、`intersection`、`merge`、双向迭代)。启用 `serde`
feature 可以在这两个类型上派生 `Serialize`/`Deserialize`。
精选预设和 TCP/UDP 拆分:
```
use portspec::{preset, top_100_tcp, Proto, TaggedSpec};
// Curated, normalized list of the ports most worth a quick scan.
let scan = top_100_tcp();
assert!(scan.contains(443));
// Same thing by name; supports "top-100", "top100", "top-1000", "top1000".
assert_eq!(preset("top-100").unwrap(), scan);
// nmap-style TCP/UDP split (default proto = TCP).
let tagged: TaggedSpec = "T:22,80,443,U:53,123".parse().unwrap();
assert_eq!(tagged.tcp.count(), 3);
assert_eq!(tagged.udp.count(), 2);
assert!(tagged.contains(Proto::Udp, 53));
// Per-protocol set algebra — never crosses transports.
let other: TaggedSpec = "T:80,U:53".parse().unwrap();
let just_t22 = tagged.difference(&other);
assert!(just_t22.contains(Proto::Tcp, 22));
```
`PortSpec::nth_port(index)` 提供 O(R) 的随机访问,并且
`services_for(port)` 会遍历内嵌表中注册到某个端口的所有名称。
从 CLI 中:
```
portspec --resolve 22,80,443 # 22ssh, ...
portspec --preset top-100 --count # 101
portspec --tagged "T:22,80,U:53,123" # tcp 22\ntcp 80\nudp 53\nudp 123
```
## 设计说明
- **无网络操作。** 此 crate 是纯端口算术;它从不打开 socket
或解析名称。在构建脚本和热循环中是安全的。
- **始终保持标准化。** `PortSpec` 保持其范围已排序、合并且
不重叠,因此包含关系检查是二分搜索,相等性是结构性的。
- **`#![forbid(unsafe_code)]`。**
## 许可证
根据您的选择,受 [Apache-2.0](LICENSE-APACHE) 或 [MIT](LICENSE-MIT) 其中之一授权。
标签:Rust, 可视化界面, 开发库, 文档结构分析, 端口管理, 网络流量审计, 网络端口, 解析器, 通知系统