How to Base64 encode and decode on a Mac
Base64 is an encoding, not encryption. Learn Base64 vs Base64URL, what the = padding means, and the macOS Terminal commands to encode and decode text and files.
Sanjeev Maharjan5 min read
On a Mac, encode text to Base64 in Terminal with echo -n 'text' | base64 and decode it with echo 'dGV4dA==' | base64 -D. Use -n so echo does not add a hidden new line. Remember that Base64 only changes how bytes are written down; it is an encoding anyone can reverse, not a way to hide anything.
The short version: base64 encodes, base64 -D decodes (recent macOS also accepts -d). Base64URL swaps +/ for -_ and usually drops the = padding. Base64 is not encryption.
What Base64 is
Base64 is a way to write any bytes using only 64 safe characters: A to Z, a to z, 0 to 9, + and /. It exists because many systems, such as email, JSON, URLs and HTTP headers, are built for text and can mangle raw binary data. Base64 lets you carry an image, a key or a file through those systems as plain text.
It works by taking the input three bytes at a time and writing each group of three as four characters. That makes the output about a third larger than the input, which is the price of being safe to send anywhere.
Encoding is not encryption
This needs saying plainly, because it causes real security mistakes. Base64 has no key and no secret. Anyone who sees a Base64 string can decode it in a second. A password or API key written in Base64 is still a password or API key in plain sight; it just looks less obvious to a human skimming a file.
If you find credentials stored as Base64 in a config file or a Kubernetes secret, treat them exactly as if they were written out in full. If you need to protect data, you need encryption. If you need to check data has not changed, you need a hash, which the guide on MD5 vs SHA-256 checksums explains.
Base64 vs Base64URL, and padding
Standard Base64 uses + and /, and both mean something in a URL. Base64URL is the same idea with two characters changed so it can go in a URL or a file name untouched:
| Base64 | Base64URL | |
|---|---|---|
| Character 62 | + | - |
| Character 63 | / | _ |
| Padding | = added to make the length a multiple of 4 | Usually left off |
Padding is the = or == you see at the end of a Base64 string. It appears when the input length is not a multiple of three, and it tells the decoder how many bytes the last group holds. Some decoders insist on it. If a Base64URL string will not decode with a standard tool, swap - back to + and _ back to /, then add = until the length divides by four.
JWTs are the place most developers meet Base64URL. Each of a token's three parts is Base64URL with no padding; the guide on how to decode a JWT walks through it.
The base64 command in macOS Terminal
macOS ships a base64 command. These are the forms you will use most.
# encode a string
echo -n 'hello world' | base64
# aGVsbG8gd29ybGQ=
# decode a string
echo 'aGVsbG8gd29ybGQ=' | base64 -D
# hello world
# encode a file, and decode it back
base64 -i photo.png -o photo.txt
base64 -D -i photo.txt -o photo-copy.png
# put the result on the clipboard
echo -n 'hello world' | base64 | pbcopy
macOS has long used -D for decode. Recent versions also accept -d and --decode, which is what Linux uses, so scripts that run on both are easier to write. On Linux, base64 wraps long output at 76 characters by default; add -w 0 to get a single line.
If you prefer a language, Python has python3 -c "import base64; print(base64.b64encode(b'hello world').decode())", and Node has Buffer.from('hello world').toString('base64'), with 'base64url' available for the URL form.
Common mistakes
The new line from echo
Plain echo 'text' adds a line break to the end. That line break gets encoded too, so echo 'hello' | base64 gives aGVsbG8K, while echo -n 'hello' | base64 gives aGVsbG8=. The extra K is the new line. If a Base64 value does not match what another system produced, this is the first thing to check. printf '%s' 'hello' avoids the problem too.
Mixing up the two alphabets
Decoding Base64URL with a standard decoder, or the other way round, either fails or quietly gives the wrong bytes. Check for -, _, + and / to tell which one you have.
Decoding text that was never text
Base64 can hold any bytes. If the decoded result looks like garbage, it may be an image, compressed data or a key, not broken text. Save it to a file rather than printing it.
Character set surprises
Base64 encodes bytes, not letters. The same accented word gives different Base64 in UTF-8 and in other encodings. Use UTF-8 on both sides unless you know otherwise.
How DailyUtil does it
DailyUtil's Base64 tool is one of the free tools in the Mac app. It encodes and decodes on your Mac, offline, so nothing you paste is sent anywhere by the tool. If what you are looking at is a token rather than plain Base64, the JWT Debugger decodes it, and the URL Encode tool handles percent encoding. If the decoded text turns out to be JSON, the guide to fixing invalid JSON and the JSON Format tool take it from there. You can download DailyUtil for macOS 14 or later on Apple Silicon.
Questions people ask
Is Base64 secure?
No. Base64 is an encoding with no key, so anyone can reverse it instantly. It makes data safe to transport as text, not safe from being read. Use encryption to protect data and treat Base64 secrets as plain text.
Why does my Base64 end in an equals sign?
The equals sign is padding. Base64 works in groups of three bytes, and when the input does not divide evenly, one or two equals signs fill the last group so the decoder knows where the data ends.
What is the difference between base64 -D and -d on a Mac?
Both decode. macOS traditionally used -D, while Linux uses -d. Recent macOS versions accept -d and --decode as well, so either works there, but -D is the safe choice on older Macs.
Why is my Base64 different from another tool's output?
Usually a hidden new line from echo was encoded, or one side used Base64URL. Encode with echo -n or printf, and check whether the other output uses dashes and underscores instead of plus and slash.
Written by Sanjeev Maharjan
Sanjeev Maharjan builds DailyUtil, developer tools for the Mac. Found a mistake in this guide? Write to [email protected].