Text processing
base64
Encode binary data as base64 text, or decode base64 back to the original bytes with -d.
base64 [OPTION...] [FILE]
Base64 represents arbitrary bytes using only 64 safe characters (A-Z, a-z, 0-9, +, /)
plus = for padding. Every 3 input bytes become 4 output characters, so the encoded form is
about a third larger. It exists to carry binary data through channels built for text: email
attachments, JSON fields, HTTP headers, data URLs, Kubernetes secrets, keys pasted into a
terminal.
base64 FILE encodes, base64 -d decodes. GNU base64 wraps encoded output at 76 characters
per line; -w 0 turns wrapping off, which is what you want inside a variable, a header or JSON.
Base64 is an encoding, not encryption. Anyone can decode it, so "base64-encoded" secrets are exactly as secret as plain text.
Examples
Encode a string
printf 'hello' | base64
aGVsbG8=
Five bytes become aGVsbG8=; the = pads the last group of 4 characters because 5 is not a multiple of 3.
Trap: echo adds a newline that gets encoded
echo 'hello' | base64
printf 'hello' | base64
aGVsbG8K aGVsbG8=
echo appends a newline, so the first command encodes 6 bytes and gives aGVsbG8K, where
the trailing K carries the newline. For passwords and tokens use printf (or echo -n)
so the encoded value contains only what you meant.
Decode base64
echo 'aGVsbG8sIHdvcmxkCg==' | base64 -d
hello, world
-d turns the text back into the original bytes: hello, world and a newline.
Encode a binary file
base64 photos/IMG_2041.png | head -n 3
iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAIAAAD+Tyo8AAACDklEQVR42u3TQQkAAAwDseqs4sma h/0GgSg4uLQDPBUJwMCAgQEDg4EBAwMGBgwMBgYMDBgYDAwYGDAwYGAwMGBgwMCAgcHAgIEBA4OB AQMDBgYMDAYGDAwYGDAwGBgwMGBgMDBgYMDAgIHBwICBAQODgVUAAwMGBgwMBgYMDBgYMDAYGDAw
The PNG becomes plain text, wrapped at 76 characters per line. Every PNG starts with
iVBORw0KGgo, the base64 form of its signature bytes.
One long line without wrapping
base64 -w 0 todo.txt; echo
YnV5IG1pbGsKZml4IGxvZ2luIGJ1Zwp3cml0ZSB0ZXN0cwpmaXggbG9nb3V0IGJ1ZwpkZXBsb3kgdjIuNAo=
-w 0 disables line wrapping, so the whole file is a single line that fits into a variable,
a JSON value or an HTTP header. base64 does not add a final newline in this mode, hence the echo.
Encode and decode a file without loss
base64 photos/IMG_2041.png > image.b64
base64 -d image.b64 > copy.png
cmp photos/IMG_2041.png copy.png && echo identical
wc -c photos/IMG_2041.png image.b64
identical 583 photos/IMG_2041.png 791 image.b64 1374 total
Decoding restores the file byte for byte. The text form is 791 bytes for a 583-byte image: a third larger, plus the newlines from wrapping.
Build an HTTP Basic auth header
token=$(printf 'alice:s3cret' | base64)
curl -s -H "Authorization: Basic $token" http://localhost:8080/private/report.txt | head -n 3
Quarterly report: confidential
HTTP Basic authentication sends user:password base64-encoded. The test server accepts the
header and returns the report. (curl -u alice:s3cret does the same encoding for you.)
Make a data URL for HTML or CSS
printf 'data:image/png;base64,%s\n' "$(base64 -w 0 photos/IMG_2041.png)" | cut -c 1-60
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAIAAA
A data URL embeds a small file directly in a web page. The output is cut to 60 characters here; the real value is one long line.
Invalid input
echo 'aGVs!bG8K' | base64 -d
helbase64: invalid input
! is not a base64 character. GNU base64 decodes up to that point (hel), then stops with
invalid input and status 1.
Skip characters that are not base64
echo 'aGVs!bG8K' | base64 -d -i
hello
-i ignores non-alphabet characters, so the stray ! is skipped and hello decodes completely.
The URL-safe alphabet
printf '??>>' | base64
printf '??>>' | basenc --base64url
Pz8+Pg== Pz8-Pg==
Standard base64 uses + and /, which have meaning in URLs. The URL-safe variant used by
JWTs replaces them with - and _. base64 has no option for it, but its coreutils sibling
basenc --base64url does.
Common pitfalls
echo secret | base64encodes the trailing newline too. Useprintf '%s' secret | base64.Wrapped output (76 characters per line) breaks headers, environment variables and JSON. Use
-w 0when the value must be one line.Base64 is not encryption. Kubernetes secrets and similar "encoded" values are readable by anyone with
base64 -d.JWTs and many APIs use URL-safe base64 without padding. Standard
base64 -drejects the-and_characters; translate them withtr '_-' '/+'or usebasenc --base64url -d.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
Older macOS versions decode with
base64 -D(capital D); recent ones accept-das well. macOS does not wrap lines by default, while GNU wraps at 76 characters. Its-boption sets the wrap width instead of GNU's-w.
Options worth knowing
A selection, described in our own words. For the full list, see base64(1) or base64 --help.
| Option | What it does |
|---|---|
-d, --decode | Decode base64 input back to bytes. |
-w, --wrap COLS | Wrap encoded lines after COLS characters; 0 disables wrapping. |
-i, --ignore-garbage | When decoding, skip characters outside the base64 alphabet. |
Related
xxdMake a hex dump of a file, or turn a hex dump back into binary with -r.odDump a file's bytes as octal, hex, decimal or characters, to see exactly what it contains.curlTransfer data to or from a URL; the standard tool for HTTP requests, API calls and downloads from the shell.sha256sumCompute SHA-256 checksums of files, or verify files against a list of checksums with -c.