base64 Command: Encoding and Decoding Basics

base64 Command: Encoding and Decoding Basics

What You'll Learn

  • How to encode and decode strings and files with base64
  • How to avoid the newline trap that echo adds
  • Common options like -w (wrap) and -d (decode)
  • The most important point: base64 is not encryption

Who this is for: Linux beginners who saw a base64 string in an API token or email attachment and wondered "what is this?"

Intro: Lina's Mystery String

Lina: Linny-senpai, I found a weird string like SGVsbG8gV29ybGQ= in a config file. What is it? An encrypted password?
Linny-senpai: Good eye. That's a string encoded with base64. But one important thing up front: it is not encryption.
Lina: Not encryption? So anyone can read what's inside?
Linny-senpai: Exactly. Just run it through base64 -d and anyone can get the original back. So it can't protect secrets. Today let's look at the basics of base64 and why it exists.

Quick Summary

  • base64 represents binary data using only ASCII characters (A-Z, a-z, 0-9, +, /, =)
  • Encode with base64, decode with base64 -d
  • It is not encryption. Anyone can decode it. Never use it to protect secrets

1. What Is base64?

Conclusion: base64 converts binary data into 64 ASCII characters. It is packaging for transport, not encryption.

Lina: Why do we even need this conversion in the first place?
Linny-senpai: Good question. Email and some protocols can only safely carry text (ASCII characters). If you push raw binary like an image through them, it can get corrupted along the way.
Lina: So converting it to text first makes it safe to transport.
Linny-senpai: Right. base64 represents any data using just 64 characters. So it's not "encryption," it's packaging for transport. The contents aren't hidden, but the form is safe to move around.

Where base64 is used

  • Email attachments (MIME)
  • HTTP Basic authentication headers
  • Binary embedded in config files / JSON (images, certificates)
  • data: URLs (embedding images directly in HTML)

2. Encoding a String

Conclusion: Pipe with echo -n into base64. Without -n, the trailing newline gets encoded too.

Linny-senpai: Let's actually encode a string first. We'll convert Hello World.
Lina: So we pipe it into base64 with |.
$ echo -n "Hello World" | base64
SGVsbG8gV29ybGQ=

Don't forget the -n in echo -n

By default echo adds a trailing newline. Without -n, that one newline character (\n) gets encoded too, changing the result.

Lina: What happens if I leave out -n?
Linny-senpai: One test makes it obvious. With the newline mixed in, the last few characters change.
$ echo "Hello World" | base64
SGVsbG8gV29ybGQK

SGVsbG8gV29ybGQ= vs SGVsbG8gV29ybGQK

The ending differs: = (no newline) vs K (includes the \n). When base64-encoding a token or password, this newline contamination is a classic bug, so always use echo -n or printf.

# printf adds no newline, so it avoids the missing -n problem
$ printf '%s' "Hello World" | base64

3. Decoding

Conclusion: Use base64 -d (or --decode). Anyone can run it, so it offers no secrecy.

Linny-senpai: Now the reverse. Let's turn that SGVsbG8gV29ybGQ= back. Just add -d.
Lina: Decoding doesn't need a special key or anything?
Linny-senpai: Nope. That's exactly why I said "it's not encryption" at the start. Anyone with the command can see the contents.
$ echo "SGVsbG8gV29ybGQ=" | base64 -d
Hello World

-d and --decode are the same

Both base64 -d and base64 --decode work. The short -d is more common.

Lina: So that mystery string in the config file is readable too...
Linny-senpai: Exactly. So never think you "hid" an API key or password just by base64-encoding it. To hide something you need encryption (like openssl).

4. Encoding and Decoding Files

Conclusion: Pass a filename to encode; redirect the -d output to a file to restore it.

Linny-senpai: It's not just strings. You can pass a file directly. Binary like images or certificates works too.
# Encode a file and save as .b64
$ base64 image.png > image.png.b64

# Decode the .b64 back into the original file
$ base64 -d image.png.b64 > restored.png
Lina: Is the restored file really identical to the original?
Linny-senpai: Good point. You can check with diff or md5sum. If they match, the restore was perfect.
# Verify the original and restored files are identical
$ diff image.png restored.png && echo "OK: identical"
OK: identical

Size grows by about 1.33x

base64 turns 3 bytes into 4 characters, so the encoded output is about 4/3 (roughly 33% larger) than the original. Watch out when base64-encoding large files where storage is tight.

5. Controlling Line Wrap with -w

Conclusion: base64 wraps at 76 characters by default. Use -w 0 for a single line.

Lina: When I encoded a long file, it got broken into multiple lines. Is that normal?
Linny-senpai: It's normal. base64 inserts a newline every 76 characters (wrapping) by default. That matches the MIME spec for email.
Lina: But sometimes I want one line, like to handle a token on a single line.
Linny-senpai: Then use -w 0. -w is "wrap," and 0 means no wrapping.
# No wrapping (single line)
$ base64 -w 0 image.png > oneline.b64

# Wrap every 40 characters
$ echo -n "Hello World, this is a longer text" | base64 -w 40

macOS base64 has no -w

-w is a GNU coreutils (standard Linux) option. The macOS (BSD) base64 has no -w and controls wrapping differently. This article assumes Linux (GNU coreutils).

6. Common Pitfalls

Conclusion: "mistaking it for encryption," "echo newline contamination," and "invalid input on decode" are the three big stumbling blocks.

Linny-senpai: Finally, let me sum up three points beginners trip on.

Pitfall 2: echo newline contamination

As we saw in section 2, forgetting echo -n encodes the newline too. When a base64-encoded token fails authentication, suspect this first.

Pitfall 3: invalid input on decode

If a space or stray character sneaks in during copy-paste, you get base64: invalid input. Use -i (--ignore-garbage) to ignore non-alphabet characters and decode anyway.

# Ignore stray newlines or spaces while decoding
$ base64 -d -i messy.b64

Safe templates (copy-paste)

# Encode a string (no newline added)
printf '%s' "text" | base64

# Encode on one line (no wrapping)
base64 -w 0 file.bin

# Decode
echo "SGVsbG8=" | base64 -d

7. Mini Exercise: Try It Yourself

Conclusion: Three tasks (encode, round-trip, newline difference) help cement how base64 behaves.

Linny-senpai: To lock in what you learned, try these on your own machine.

Task 1: Encode your own name with base64 (without a newline)

Task 2: Decode the Task 1 output with base64 -d and confirm it returns the original

Task 3: Encode both echo -n "test" and echo "test", then explain in one line why the results differ

Task 1 hint
printf '%s' "Your Name" | base64

Using printf '%s' or echo -n avoids mixing in a trailing newline.

Task 2 hint
echo "(Task 1 output)" | base64 -d

If your original name appears as-is, the round trip succeeded.

Task 3 hint

echo adds a trailing newline (\n) by default. echo "test" encodes test\n (5 bytes) while echo -n "test" encodes test (4 bytes), so the resulting base64 strings differ.

Next Reading