Skip to content
shellmap

Encode a string to base64

Convert a string (or file) to its base64 representation — for HTTP basic auth headers, JWT payloads, embedded credentials in YAML, or any text-only transport of binary.

How to encode a string to base64 in each shell

Bashunix
echo -n "hello" | base64

**Critical**: `echo -n` suppresses the trailing newline. WITHOUT `-n`, `echo "hello" | base64` encodes the 6 bytes `hello\n` instead of the 5 bytes `hello` — different base64 output, and EVERY downstream consumer that validates the decoded string will fail. The corresponding decode: `echo "aGVsbG8=" | base64 -d`. For files: `base64 file.bin > file.b64`. For URL-safe variant (replaces `+/` with `-_`): `base64 | tr '+/' '-_' | tr -d '='` (the trailing `=` padding is optional in URL-safe form).

Zshunix
echo -n "hello" | base64

Same external `base64` binary. macOS BSD `base64` is mostly compatible with GNU `base64` — both accept stdin and a `-d` decode flag. One difference: GNU `base64` wraps output at 76 columns by default (`-w 0` to disable); macOS BSD `base64` does NOT wrap by default. Scripts that pipe through `base64` and `grep`/`cut` on the encoded string need `-w 0` on Linux.

Fishunix
echo -n "hello" | base64

Fish `echo -n` works as expected (no trailing newline). For "encode multi-line input as one base64 blob": `printf 'line1\nline2\n' | base64`. For URL-safe + no-padding base64 (JWT-style): `echo -n "hello" | base64 | tr -d '=' | tr '+/' '-_'`.

PowerShellwindows
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("hello"))

Always pick the encoding explicitly — `[Text.Encoding]::UTF8` is the conventional choice for text. `[Text.Encoding]::Default` is system-locale-dependent (CP1252 on Western Windows, UTF-8 on modern Linux pwsh) — surprising bugs. For file input: `[Convert]::ToBase64String([IO.File]::ReadAllBytes("file.bin"))`. Decode: `[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("aGVsbG8="))`. URL-safe variant: no built-in; use the conventional `.Replace("+","-").Replace("/","_").TrimEnd("=")` chain.

cmd.exewindows
certutil -encode infile outfile

cmd has NO inline base64 — `certutil -encode` is the closest, but it requires both input and output to be FILES (no stdin). It also wraps in `-----BEGIN CERTIFICATE-----` headers by default — strip with `findstr /v "CERTIFICATE"` post-encoding. For inline encoding, shell out to pwsh: `powershell -NoProfile -Command "[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('hello'))"`. The cmd-only path is genuinely awkward — pwsh is the answer.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • The trailing-newline trap is the #1 cause of "my base64-encoded basic auth doesn't work" bug reports. `echo "user:pass" | base64` includes the `\n` and decodes to `user:pass\n` — the server treats this as a wrong password. Always `echo -n` (or `printf "%s"` which never adds a newline). pwsh has the same trap if you do `Add-Content` (adds newline) vs `Set-Content -NoNewline` or direct `.ToBase64String`.
  • Standard base64 (RFC 4648 §4) uses `+` and `/`. URL-safe base64 (§5) uses `-` and `_` so the encoded value can appear in URL query strings / path segments without percent-encoding. JWTs use URL-safe base64 WITHOUT padding (no trailing `=`). When in doubt about which a tool produces, decode a known input (`hello` → `aGVsbG8=` standard, `aGVsbG8` URL-safe-unpadded) and compare.
  • Base64 expands data by 33% (3 input bytes → 4 output chars). This matters for size-sensitive contexts — embedding a 10MB image in JSON as base64 produces ~13MB of JSON. For HTTP payloads, prefer `multipart/form-data` (raw binary) over base64-in-JSON when both are options.
  • For "encode binary blob in a YAML / JSON config" specifically, kubectl/helm/etc. expect base64 WITHOUT line wraps. `base64 -w 0 file.bin` (GNU) or `base64 file.bin | tr -d '\n'` (BSD-compatible) produces a single-line blob. The 76-char-wrap default (RFC 2045 MIME-style) breaks YAML parsers that expect a single scalar value.

Related commands

Related tasks