addressFromBytes(bytes: Uint8Array): Address
Reads an IPv4 or IPv6 address from a buffer, picking the version from its length.
bytes must be exactly 4 bytes (read as IPv4, returning number) or
exactly 16 (read as IPv6, returning bigint). Any other length throws a
RangeError rather than guessing.
There is deliberately no offset parameter. An offset would make the width
depend on how much data happens to trail the field rather than on the
caller's intent — a 4-byte address 8 bytes from the end of a frame would
read as IPv4, and the same field in the same position would read as IPv6 the
day the frame grew. Pass the exact bytes instead, with
packet.subarray(12, 16), which is a non-copying view; or, when the version
is already known, use addressv4FromBytes or addressv6FromBytes, which
do take an offset because their width comes from the function rather than
from the buffer.
Unlike parseAddress, this does not unwrap IPv4-mapped addresses.
Sixteen bytes always return a bigint, so that
addressToBytes(addressFromBytes(b)).length === b.length. Callers wanting the
dual-stack normalization compose unmapToAddressv4 explicitly.
The length picks the version
The length picks the version
import { assertEquals } from "@std/assert"; import { addressFromBytes } from "@hertzg/ip/bytes"; import { stringifyAddress } from "@hertzg/ip/address"; assertEquals(stringifyAddress(addressFromBytes(new Uint8Array([10, 0, 0, 1]))), "10.0.0.1"); assertEquals(stringifyAddress(addressFromBytes(new Uint8Array(16))), "::");
Sixteen mapped bytes stay IPv6
Sixteen mapped bytes stay IPv6
import { assertEquals } from "@std/assert"; import { addressFromBytes, addressToBytes } from "@hertzg/ip/bytes"; import { unmapToAddressv4 } from "@hertzg/ip/addressv6"; import { stringifyAddressv4 } from "@hertzg/ip/addressv4"; // deno-fmt-ignore const mapped = new Uint8Array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 1, 1, ]); const address = addressFromBytes(mapped); assertEquals(typeof address, "bigint"); assertEquals(addressToBytes(address).length, 16); // Normalizing to IPv4 is an explicit, separate step assertEquals(stringifyAddressv4(unmapToAddressv4(address as bigint)), "192.168.1.1");
Any other length throws instead of guessing
Any other length throws instead of guessing
import { assertThrows } from "@std/assert"; import { addressFromBytes } from "@hertzg/ip/bytes"; assertThrows(() => addressFromBytes(new Uint8Array(20)), RangeError); assertThrows(() => addressFromBytes(new Uint8Array(6)), RangeError);
Reading a field out of a frame, by slicing rather than offsetting
Reading a field out of a frame, by slicing rather than offsetting
import { assertEquals } from "@std/assert"; import { addressFromBytes } from "@hertzg/ip/bytes"; import { addressv4FromBytes } from "@hertzg/ip/bytesv4"; import { stringifyAddress } from "@hertzg/ip/address"; // deno-fmt-ignore const packet = new Uint8Array([ 0x45, 0x00, 0x00, 0x54, 0x1c, 0x46, 0x40, 0x00, 0x40, 0x06, 0x00, 0x00, 10, 0, 0, 1, 192, 168, 1, 1, ]); // `subarray` is a view, not a copy, and it states the width assertEquals(stringifyAddress(addressFromBytes(packet.subarray(12, 16))), "10.0.0.1"); // When the version is known, the version-specific function takes the offset assertEquals(addressv4FromBytes(packet, 12), addressFromBytes(packet.subarray(12, 16)));
bytes: Uint8Array
The buffer to read, which must be exactly 4 or 16 bytes long
The address as number (IPv4) or bigint (IPv6)