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
Metadata
Release files for cidr-aggregator 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cidr_aggregator-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / cidr_aggregator-0.1.0-py3-none-any.whl
| Download URL | cidr_aggregator-0.1.0-py3-none-any.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3bee5370555437a9dc711d2e00c252fa64e180903b84b30be60cba7aab074348
|
|
BLAKE2b-256 checksum How to use checksums |
a9157e9a012ccc7d4347b91adc816e0c84600b11fab0dc27d801f13bcecc10eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 10, 2026.
Transparency log