function compareCidrv4
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).

Examples

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

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

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);

Parameters

The first CIDR block

The second CIDR block

Return Type

-1 | 0 | 1

-1 if a sorts before b, 1 if after, 0 if equal