# encoding.hex
`hexEncode([222, 173, 190, 239])` is `"deadbeef"`, and `hexDecode("DEADbeef")`
is `[222, 173, 190, 239]`. This is base16 from RFC 4648 section 8, the form
digests and keys are usually printed in.
**Bytes are lists of integers.** The registry's type vocabulary has no bytes
type, so every encoding and crypto capability (`encoding.*`, `crypto.*`,
`auth.*`) takes and returns bytes as `int[]`, each 0 to 255. In Python a
`bytes` value is already a sequence of such integers and can be passed
directly (`hex_encode(b"\x00\xff")`); the result is a `list`, so wrap it in
`bytes(...)` when you need one. In TypeScript pass a plain array
(`Array.from(uint8array)`). Anything else in the list (256, -1, 1.5, a
string, `true`) is an error, never silently truncated to a byte.
Encoding writes lowercase, which is what `sha256sum`, Python's `bytes.hex()`
and most JSON APIs print. RFC 4648 writes its test vectors in uppercase;
decoding accepts either case, and mixed case, so both round-trip.
Decoding is strict on purpose: an odd number of digits, a `0x` prefix,
spaces, a trailing newline or a non-ASCII digit such as `"٠٠"` are errors
rather than being skipped, because a permissive decoder turns a pasted typo
into different key material without anyone noticing.
Source: RFC 4648, The Base16, Base32, and Base64 Data Encodings, section 8
and the test vectors in section 10 (https://www.rfc-editor.org/rfc/rfc4648).