Encodings
If you're encoding some binary data as text, you have a lot of options. My cheatsheet:
| encoding | transport-safe | length | standard | case-sensitive |
|---|---|---|---|---|
| hex | safe | long | yes | no |
| base32 | safe | medium | meh | no |
| base58 | safe | short | no | yes |
| base64 | meh | short | yes | yes |
| base64url | safe | short | yes | yes |
- transport-safe mostly meaning whether it'll survive being a url parameter. base64 includes
+and-which necessitates base64url. - everything technically has a standard but the question is if they're standardized, and for example node.js only supports Buffer encoding to base64, base64url, and hex.
- i enjoy @scure/base for using JavaScript and encoding in other base systems.
My current defaults:
- base58check for API tokens. Short, quick to validate if it's a valid token or not. Unlike base64, fewer ambiguous characters.
- base64url for encrypted cookies.
- base64 for putting longer text into the environment, like JWKS keys or certificates. Somewhat safer than sticking the raw text in there.
- base32 for user-facing tokens, like invite codes. Good combination of efficiency and safety. Very safe to copy & paste.
- hex for encryption keys in the environment. Doesn't really matter that they're a little long, super easy to generate and copy and paste with
openssl rand -hex.
I feel a pull to consolidate these further and ask whether I'm being too fancy using different encodings. In particular, whether all encryption keys should be base64 encoded, and whether we really need base32 for user-facing content. Though base32 subjectively looks nice and is short, it's pretty nonstandard: no support in Node, and the main place where I see base32 in use, in the AT Protocol, they use a different character set than usual.