Aggregate, reverse, and difference CIDR IP ranges.
Project description
cidr-aggregator
Aggregate, reverse, and difference CIDR (IP range) entries. Both IPv4 and IPv6 are supported.
Features
- Aggregate — merge overlapping and adjacent CIDR ranges into a minimal set
- Reverse — compute the complement (all IPs not in the given ranges)
- Difference — subtract one set of ranges from another
- Exclude reserved — filter out special-purpose addresses (RFC 5735, RFC 6890)
- IPv4 + IPv6 — unified API via the
IpRangetrait
Usage
CLI
Install with uv (recommended):
# Run directly
uvx cidr-aggregator --help
# Or install permanently
uv tool install cidr-aggregator
Or install with Cargo:
cargo install cidr-aggregator --features cli
Pipe CIDRs from stdin:
cat ip-list.txt | cidr-aggregator
curl -s https://example.com/ip-list.txt | cidr-aggregator
Read from a file:
cidr-aggregator -f input.txt -o output.txt
Reverse (compute complement of all input ranges):
cidr-aggregator -r < ranges.txt
Exclude reserved/private IPs:
cidr-aggregator -x < ranges.txt
Show statistics (address count, line count):
cidr-aggregator -s < ranges.txt
Library
Add to your Cargo.toml:
[dependencies]
cidr-aggregator = "0.1"
Aggregate overlapping and adjacent blocks into a minimal set:
use cidr_aggregator::{Aggregator, parse_cidrs};
let (mut v4_ranges, _, _) = parse_cidrs("10.0.0.0/24\n10.0.1.0/24\n10.0.0.128/25");
// Adjacent .0.0/24 + .1.0/24 → .0.0/23; .0.128/25 is inside the /23
v4_ranges.aggregate();
// Aggregate produces minimal ranges but not necessarily canonical CIDR
// blocks — normalize() is required before export().
v4_ranges.normalize();
assert_eq!(v4_ranges.export(), "10.0.0.0/23");
Chain operations in a pipeline — filter reserved addresses, then reverse:
use cidr_aggregator::{Aggregator, parse_cidrs, IpRange, Ipv6Range};
let (_, v6_ranges, _) = parse_cidrs("2001:db8::/32\n64:ff9b::/96");
println!(
"{}",
v6_ranges
.aggregated()
.differenced(Ipv6Range::reserved()) // strip RFC 6890 reserved blocks
// Normalize is required to produce valid CIDR blocks after aggregation
// and difference, which may leave non-canonical ranges.
.normalized()
.reversed()
.export());
See the API documentation for all available operations.
Web App
Also available as a WASM-powered web app at:
License
MIT OR Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cidr_aggregator-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cidr_aggregator-0.1.0-py3-none-any.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bee5370555437a9dc711d2e00c252fa64e180903b84b30be60cba7aab074348
|
|
| MD5 |
ecdc0bb742c55577e8cd71ab5fd47be1
|
|
| BLAKE2b-256 |
a9157e9a012ccc7d4347b91adc816e0c84600b11fab0dc27d801f13bcecc10eb
|
Provenance
The following attestation bundles were made for cidr_aggregator-0.1.0-py3-none-any.whl:
Publisher:
build.yml on Gowee/cidr-aggregator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cidr_aggregator-0.1.0-py3-none-any.whl -
Subject digest:
3bee5370555437a9dc711d2e00c252fa64e180903b84b30be60cba7aab074348 - Sigstore transparency entry: 1776094495
- Sigstore integration time:
-
Permalink:
Gowee/cidr-aggregator@371e98db24de4d4a2b4128bc4d2f7f3ebc66e777 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Gowee
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@371e98db24de4d4a2b4128bc4d2f7f3ebc66e777 -
Trigger Event:
push
-
Statement type: