Universal IP address parsing and stringifying.

This module provides parseAddress, stringifyAddress and compareAddress that auto-detect IPv4 vs IPv6 and delegate to the appropriate version-specific function. The Address and ParsedAddress type aliases are also exported for working with version-polymorphic address values.

For version-specific functions, see:

Examples

Parse and stringify any IP address

import { assertEquals } from "@std/assert";
import { parseAddress, stringifyAddress } from "@hertzg/ip/address";

// IPv4
const v4 = parseAddress("192.168.1.1");
assertEquals(v4, { address: 3232235777 });
assertEquals(stringifyAddress(v4), "192.168.1.1");

// IPv6
const v6 = parseAddress("2001:db8::1");
assertEquals(v6, { address: 42540766411282592856903984951653826561n });
assertEquals(stringifyAddress(v6), "2001:db8::1");

// A zone ID rides along
const linkLocal = parseAddress("fe80::1%eth0");
assertEquals(linkLocal, { address: 0xfe800000000000000000000000000001n, zoneId: "eth0" });
assertEquals(stringifyAddress(linkLocal), "fe80::1%eth0");

Functions

f
compareAddress(
a: Address,
b: Address
): -1 | 0 | 1

Compares two IP addresses of either version for sorting.

f
parseAddress(
address: string,
options?: ParseOptions
): ParsedAddress

Parses an IPv4 or IPv6 address string, with an optional zone ID, to its numeric value.

f
stringifyAddress(address: Address | ParsedAddress): string

Stringifies an IPv4 (number) or IPv6 (bigint) address, bare or parsed, to its standard notation.

Type Aliases

T
Address = Addressv4 | Addressv6

A plain IP address of either IP version.

T
Addressv4 = number

An IPv4 address as a 32-bit unsigned integer, 0 to 4294967295. The primitive type is what carries the version: a number is IPv4, a bigint is IPv6 (ADR 0001).

T
Addressv6 = bigint

An IPv6 address as a 128-bit unsigned bigint, 0n to 2n ** 128n - 1n. The primitive type is what carries the version: a bigint is IPv6, a number is IPv4 (ADR 0001).

T
ParsedAddress = ParsedAddressv4 | ParsedAddressv6

What parseAddress returns and what stringifyAddress accepts: a ParsedAddressv4 or a ParsedAddressv6. Read .address for the bare Address and narrow with typeof; the zone never touches the value, and no operation in this package reads it.

T
ParsedAddressv4 = { readonly address: Addressv4; readonly zoneId?: ZoneId; }

What parseAddressv4 returns and what stringifyAddressv4 accepts: the address, plus the zone ID if the notation had one. Read .address for the bare Addressv4; the zone never touches the value, and no operation in this package reads it.

T
ParsedAddressv6 = { readonly address: Addressv6; readonly zoneId?: ZoneId; }

What parseAddressv6 returns and what stringifyAddressv6 accepts: the address, plus the zone ID if the notation had one. Read .address for the bare Addressv6; the zone never touches the value, and no operation in this package reads it.

T
ParseOptions = { readonly unmapToV4?: boolean; }

Options for the universal parsers, parseAddress and parseCidr. The version-specific parsers take none: they return their own version and nothing else.

  • unmapToV4: boolean

    Whether an IPv4-mapped IPv6 address (::ffff:a.b.c.d) is returned as the IPv4 value it carries. Defaults to true (ADR 0004): dual-stack listeners report IPv4 clients in the mapped form, and almost every caller wants the IPv4 view. Set to false to keep the bigint.

T
ZoneId = string

The zone ID of an address, the interface tail after % in fe80::1%eth0 (RFC 4007 section 11). Carried verbatim by the Parsed* types; never percent-decoded, so %25eth0 is the zone 25eth0.