Skip to content
LogoLogo

@portable/bytes

Functions

Bytes.concat

Joins byte arrays into one new array. The result never shares memory with the input, even for a single chunk.

function concat(chunks: readonly Uint8Array[]): Uint8Array<ArrayBuffer>;
import * as Bytes from '@portable/bytes';
 
Bytes.concat([new Uint8Array([1, 2]), new Uint8Array([3])]); // Uint8Array [1, 2, 3]

Bytes.equal

Whether two byte arrays hold the same bytes. Returns at the first difference, so the time it takes shows where the arrays differ. Compare secrets with timingSafeEqual instead.

function equal(a: Uint8Array, b: Uint8Array): boolean;
import * as Bytes from '@portable/bytes';
 
Bytes.equal(new Uint8Array([1, 2]), new Uint8Array([1, 2])); // true

Bytes.timingSafeEqual

Whether two byte arrays hold the same bytes, in time that depends only on their length. Use it to compare a secret, such as a signature or a token, with a value an attacker sent.

Arrays of different lengths return false at once, so the length itself isn't secret. That holds for a signature or a hash, whose length is fixed by the algorithm.

function timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
import * as Bytes from '@portable/bytes';
 
const expected = new Uint8Array(
  await crypto.subtle.sign('HMAC', key, body),
);
if (!Bytes.timingSafeEqual(expected, Bytes.fromHex(signature))) {
  throw new Error('Bad signature');
}

Bytes.fromHex

Decodes hex to bytes. Uses Uint8Array.fromHex where the runtime has it. Upper and lower case digits are both accepted. Anything else, including whitespace and a 0x prefix, throws.

function fromHex(text: string | Uint8Array): Uint8Array<ArrayBuffer>;

Throws

  • InvalidInputError When the input has an odd length or a character that isn't a hex digit.
import * as Bytes from '@portable/bytes';
 
Bytes.fromHex('000f10FF'); // Uint8Array [0, 15, 16, 255]

Bytes.toHex

Encodes bytes as lowercase hex. Uses Uint8Array.prototype.toHex where the runtime has it.

function toHex(bytes: Uint8Array): string;
import * as Bytes from '@portable/bytes';
 
Bytes.toHex(new Uint8Array([0, 15, 16, 255])); // '000f10ff'

Errors

Bytes.InvalidInputError

Thrown by fromHex for input of odd length or with a character that isn't a hex digit.

class InvalidInputError extends Errors.InvalidInputError {
  readonly kind: string;
}
import * as Bytes from '@portable/bytes';
 
try {
  Bytes.fromHex('0g');
} catch (error) {
  if (error instanceof Bytes.InvalidInputError) {
    console.log(error.message);
  }
}