function parseAddressv6
parseAddressv6(address: string): ParsedAddressv6

Parses an IPv6 address in colon-hexadecimal notation, with an optional zone ID, to its numeric value.

The notation is address [ "%" zoneId ] (ADR 0003). The address grammar is exactly RFC 4291 section 2.2 and nothing else:

  • Full form: 2001:0db8:0000:0000:0000:0000:0000:0001
  • Compressed form with ::: 2001:db8::1
  • Mixed IPv4 form: ::ffff:192.168.1.1, the dotted quad only as the last field

A group is 1-4 hex digits, with no 0x, no sign and no trailing text; :: covers one or more groups, so at most seven may be written alongside it; and whitespace is accepted nowhere, including around the whole string. The zone ID, when present, is carried verbatim: it may not contain %, / or whitespace, is never percent-decoded (%25eth0 is the zone 25eth0), and never touches the numeric value.

A prefix is not accepted; that is parseCidrv6's slot. An IPv4-mapped address stays a bigint here; parseAddress is the parser that unmaps it.

Examples

Basic parsing

import { assertEquals } from "@std/assert";
import { parseAddressv6 } from "@hertzg/ip/addressv6";

assertEquals(parseAddressv6("::"), { address: 0n });
assertEquals(parseAddressv6("::1"), { address: 1n });
assertEquals(parseAddressv6("2001:db8::1"), { address: 42540766411282592856903984951653826561n });
assertEquals(parseAddressv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), { address: 340282366920938463463374607431768211455n });

Compressed forms

import { assertEquals } from "@std/assert";
import { parseAddressv6 } from "@hertzg/ip/addressv6";

assertEquals(parseAddressv6("2001:db8::"), parseAddressv6("2001:0db8:0000:0000:0000:0000:0000:0000"));
assertEquals(parseAddressv6("::ffff:192.168.1.1"), parseAddressv6("0:0:0:0:0:ffff:c0a8:0101"));

A zone ID is carried verbatim

import { assertEquals } from "@std/assert";
import { parseAddressv6 } from "@hertzg/ip/addressv6";

assertEquals(parseAddressv6("fe80::1%eth0"), { address: 0xfe800000000000000000000000000001n, zoneId: "eth0" });
assertEquals(parseAddressv6("fe80::1%12"), { address: 0xfe800000000000000000000000000001n, zoneId: "12" });
assertEquals(parseAddressv6("fe80::1%eth0.100"), { address: 0xfe800000000000000000000000000001n, zoneId: "eth0.100" });
assertEquals(parseAddressv6("fe80::1%25eth0"), { address: 0xfe800000000000000000000000000001n, zoneId: "25eth0" });

Error handling

import { assertThrows } from "@std/assert";
import { parseAddressv6 } from "@hertzg/ip/addressv6";

assertThrows(() => parseAddressv6("192.168.1.1"), TypeError);
assertThrows(() => parseAddressv6("2001:db8:::1"), TypeError);
assertThrows(() => parseAddressv6("2001:db8::1::1"), TypeError);
assertThrows(() => parseAddressv6("2001:gggg::1"), TypeError);
assertThrows(() => parseAddressv6("1:2:3:4:5:6:7:8::"), TypeError);
assertThrows(() => parseAddressv6("::1 "), TypeError);
assertThrows(() => parseAddressv6("fe80::1%"), TypeError);
assertThrows(() => parseAddressv6("fe80::1%eth0%1"), TypeError);
assertThrows(() => parseAddressv6("fe80::1/64"), TypeError);

Parameters

address: string

The address string, colon-hexadecimal with an optional %zoneId

Return Type

The address as a 128-bit bigint, and the zone ID if there was one

Throws

TypeError

If the format is invalid -- including a group that is not 1-4 hex digits, more than one ::, a :: covering no groups, whitespace, the wrong number of groups, a prefix, an empty or malformed zone ID

RangeError

If an embedded IPv4 octet is out of range, as in "::1.2.3.256". A malformed hex group is a TypeError, not this; a group cannot be numerically out of range, since 4 hex digits cannot exceed ffff.