2.0 KiB
base32/base32
(no submodules)
Purpose
RFC 4648 §6 base32 encode + decode. The OTP profile defaults to unpadded
output to match the Google Authenticator Key URI Format (secret=... is
unpadded in the wild); spec-strict consumers can opt in via padding: true.
Decode is case-insensitive and tolerates whitespace between groups so QR-code
URLs that wrap long secrets round-trip cleanly.
Features
base32Encode(bytes, opts?)— bit-packed five-at-a-time encode.base32Decode(input)— single-pass reverse-table decode.- 32-character alphabet
A–Z2–7per RFC 4648 §6. - Lower-case alias only for letters (digits 2–7 are case-invariant).
OTP.BASE32_INVALIDraised on non-alphabet character.
Usage: Basic Example
import { base32Decode, base32Encode } from "@suaveplan/otp/base32";
const bytes = base32Decode("JBSWY3DPEHPK3PXP");
const back = base32Encode(bytes);
Usage: Advanced Example
import { base32Encode } from "@suaveplan/otp/base32";
// Spec-strict consumer that needs `=` padding.
const padded = base32Encode(new Uint8Array([0x66, 0x6f, 0x6f]), {
padding: true,
});
// padded === "MZXW6==="
API Reference
base32Encode(bytes: Uint8Array, opts?: { padding?: boolean }): string— returns the base32 form.paddingdefaults tofalse.base32Decode(input: string): Uint8Array— decodes padded or unpadded input; whitespace is stripped; case-insensitive; non-alphabet characters raiseOtpError(OTP.BASE32_INVALID)with the offending position.
Implementation Notes
The decode table is a 128-entry Int8Array indexed by char-code. Letters are
aliased to their lower-case slots; digits are not aliased because '2'+32 ='R'
which would otherwise overwrite the letter slot for R. The encoder emits
unpadded output by default to match the prevailing Google Authenticator wire
format; padding: true makes the output multiple-of-eight characters and
RFC-4648-compliant for spec-strict consumers.