base64 Command: Encoding and Decoding Basics

base64 Command: Encoding and Decoding Basics

What you'll be able to do

  • Encode and decode strings and files with `base64`
  • Tell encoding, encryption, and hashing apart
  • Avoid the `echo` newline trap and the `>` overwrite

Prerequisites (read these first)

What You'll Learn

  • How to encode and decode strings and files with base64
  • How to tell encoding, encryption, and hashing apart
  • How to avoid the newline trap that echo adds
  • Common options like -w (wrap) and -d (decode)

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

Words used here (this is the part people mix up)

  • Encoding: changing how data is written. No key is involved. Anyone can turn it back. base64 is this.
  • Encryption: making data readable only to whoever holds the key. Without the key, the contents stay hidden. Tools like openssl do this.
  • Hashing: producing a short value from the contents. It cannot be reversed. It answers "are these the same?" Tools like sha256sum do this.

All three produce a strange-looking string. What differs is whether you can reverse it and whether a key is required. base64 here is the kind anyone can reverse without a key.

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 gets 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 with only 64 ASCII characters (A-Z a-z 0-9 + /). The trailing = is padding that pads the length
  • 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). Push raw binary like an image through them and it can get corrupted on 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. The resulting string changes.

Lina: Senpai, I base64-encoded an API token and sent it, but the authentication failed. I copied the string carefully.
Linny-senpai: Did you pass -n to echo?
Lina: I didn't. Can one extra newline really change that much?
Linny-senpai: It can. Let's compare the two outputs. The last few characters will be different.
$ echo "Hello World" | base64
SGVsbG8gV29ybGQK
Lina: You're right. The ending changed from = to K. So an invisible newline caused it.
Linny-senpai: Yes. One invisible character makes it different data. So make it a rule: for tokens, use echo -n or printf.

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?
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 with a key, from a tool 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. Let's make one practice file first.
# Create a practice file
$ echo "practice" > sample.txt

# Encode a file and save as .b64
$ base64 sample.txt > sample.txt.b64

# Decode the .b64 back into a restored file
$ base64 -d sample.txt.b64 > restored.txt

Binary like images or certificates goes through exactly the same steps.

Where files land, and the overwrite risk

Lina: Is the restored file really identical to the original?
Linny-senpai: Good point. Check with diff or sha256sum. If they match, the restore was perfect.
# Verify the original and restored files are identical
$ diff sample.txt restored.txt && echo "OK: identical"
OK: identical

Size grows by about 1.33x

base64 turns 3 bytes into 4 characters. 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. base64 uses exactly 64 characters (A-Z a-z 0-9 + /), and anything else is an error.

Use -i (--ignore-garbage) to skip characters outside those 64 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.

Make an empty practice directory and work inside it. That way you never overwrite a file you already had.

# Prepare a practice directory and move into it
$ mkdir -p ~/base64-practice && cd ~/base64-practice

Exercise 1: Encode your own name with base64, without a trailing newline.

Show Hint 1 (Direction)

Pipe the output of a command that prints text. Pick the form that adds no newline.

Show Hint 2 (Command name)

Use printf '%s' or echo -n, then pipe into base64.

Show Answer
$ printf '%s' "Lina" | base64
TGluYQ==

printf '%s' and echo -n both keep the trailing newline out.

Exercise 2: Decode the Exercise 1 output and confirm the original comes back.

Show Hint 1 (Direction)

Use the same command with one option that reverses the direction.

Show Hint 2 (Command name)

Use base64 -d.

Show Answer
$ echo "TGluYQ==" | base64 -d
Lina

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

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

Show Hint 1 (Direction)

You cannot see it, but one of them sends one extra character at the end.

Show Hint 2 (Command name)

Run echo -n "test" | base64 and echo "test" | base64, then compare the output.

Show Answer
$ echo -n "test" | base64
$ echo "test" | base64
dGVzdA==
dGVzdAo=

echo adds a trailing newline (\n) by default. echo "test" encodes test\n (5 bytes) while echo -n "test" encodes test (4 bytes). Different input, different base64 string.

Looking Back

Conclusion: base64 is not a way to hide data; it is a wrapper for moving it safely.

Lina: It finally clicks. base64 isn't a way to hide something — it's a way to wrap it for transport.
Linny-senpai: Exactly. Encryption needs a key, hashing can't be reversed, encoding anyone can reverse. Tell those three apart and you're fine.
Lina: That mystery string in the config file doesn't scare me now. And I see why it must never be a password store.

Three-Line Recap

Conclusion: base64 is a keyless conversion — neither encryption nor hashing.

  1. base64 is encoding, a change of writing form. Anyone reverses it with base64 -d
  2. Encryption needs a key. Hashing cannot be reversed. base64 is neither of those
  3. Use echo -n or printf for strings, and mind the > overwrite when writing files

Next Reading

Share this article

Next steps