compareCidrv4(): -1 | 0 | 1
Compares two IPv4 CIDR blocks for sorting.
Orders by address ascending, then by prefix length ascending — so where
two blocks share a start address, the shorter prefix (the larger block,
the supernet) sorts first. This is the order PostgreSQL's cidr type
uses, and the order every containing block needs to precede the blocks
it contains, which is what cidrv4Merge relies on internally.
The block is ordered as written: the address field is compared as
stored, without applying the network mask first. A block carrying host
bits therefore sorts by the address stringifyCidrv4 will print
for it, and 10.0.0.5/24 does not compare equal to 10.0.0.0/24 even
though they cover the same addresses. Normalize with
cidrv4NetworkAddress first if that is the order you want.
Both dialects are compared by mask, so 10.0.0.0/8 and
10.0.0.0/255.0.0.0 are equal, and the order is the same as by prefix
length: /8 is 0xFF000000, /9 is 0xFF800000. Comparing masks
rather than prefix lengths is what keeps a comparator total, since a
mask always exists and a prefix length does not (ADR 0006).
Sort a routing table
Sort a routing table
import { assertEquals } from "@std/assert"; import { compareCidrv4, parseCidrv4, stringifyCidrv4 } from "@hertzg/ip/cidrv4"; const routes = ["192.168.1.0/24", "10.0.0.0/16", "10.0.0.0/8"].map(parseCidrv4); assertEquals(routes.toSorted(compareCidrv4).map(stringifyCidrv4), [ "10.0.0.0/8", "10.0.0.0/16", "192.168.1.0/24", ]);
A supernet sorts before its subnets
A supernet sorts before its subnets
import { assertEquals } from "@std/assert"; import { compareCidrv4, parseCidrv4 } from "@hertzg/ip/cidrv4"; assertEquals(compareCidrv4(parseCidrv4("10.0.0.0/8"), parseCidrv4("10.0.0.0/16")), -1); assertEquals(compareCidrv4(parseCidrv4("10.0.0.0/16"), parseCidrv4("10.0.0.0/8")), 1); assertEquals(compareCidrv4(parseCidrv4("10.0.0.0/8"), parseCidrv4("10.0.0.0/8")), 0);
The dialect does not affect the order
The dialect does not affect the order
import { assertEquals } from "@std/assert"; import { compareCidrv4, parseCidrv4 } from "@hertzg/ip/cidrv4"; const prefixed = parseCidrv4("10.0.0.0/8"); const masked = { address: prefixed.address, mask: 0xFF000000 }; assertEquals(compareCidrv4(prefixed, masked), 0); assertEquals(compareCidrv4(masked, parseCidrv4("10.0.0.0/16")), -1);