Encode and Decode Files Safely with GNU base64
You will turn a file or stream into Base64 text, decode it back to its original bytes, and verify the round trip. The examples use GNU coreutils 9.4, installed here as package version 9.4-3ubuntu6.3. Allow about ten minutes. You need a shell, a readable input file, and write access to the directory where you will save the result.
The route
Jump straight to the step you need, or tick off Done means at the end.
Base64 is an encoding, not encryption. Anyone who receives the encoded text can decode it, so do not use base64 to protect passwords, tokens or private files.
1. Check the installed command
Confirm which executable your shell will run and record its version. These are ordinary, read-only commands and do not need elevated privileges:
$ command -v base64
/usr/bin/base64
$ base64 --version | head -n 1
base64 (GNU coreutils) 9.4
The command accepts one optional file name. With no file, or with -, it reads standard input. It writes the encoded or decoded bytes to standard output, so shell redirection decides where the result is saved.
Checkpoint: if command -v base64 finds nothing, install the coreutils package through your normal operating system process before continuing. Do not use sudo merely to encode a file that you can already read.
2. Encode a file as Base64 text
Replace the placeholder paths with files you control. This command does not change the input:
$ base64 /path/to/input.bin > /path/to/input.bin.b64
GNU base64 wraps encoded output after 76 characters by default. The result is still Base64 data, and newlines are permitted when it is decoded. Inspect the output without opening a potentially large file in an editor:
$ wc -c /path/to/input.bin /path/to/input.bin.b64
$ head -n 2 /path/to/input.bin.b64
For a single-line value, disable wrapping with --wrap=0:
$ base64 --wrap=0 /path/to/input.bin > /path/to/input.bin.one-line.b64
$ awk 'length > 0 { print length; exit }' /path/to/input.bin.one-line.b64
the encoded line length is printed here
The line length depends on the input size. Do not assume that a short file produces a fixed-length value.
3. Decode the text back to bytes
Use --decode, or its short form -d, and redirect the result to a new path:
$ base64 --decode /path/to/input.bin.b64 > /path/to/round-trip.bin
Verify that the decoded file is byte-for-byte identical to the original:
$ cmp --silent /path/to/input.bin /path/to/round-trip.bin
$ printf 'comparison status: %s\n' "$?"
comparison status: 0
Status 0 from cmp means the files match. A non-zero status means they differ, or that one of the paths could not be read. Keep the original file until this check succeeds.
4. Test a stream without creating an input file
Standard input and output make base64 useful in a pipeline. This example encodes a known line and immediately decodes it:
$ printf 'hello Linux\n' | base64 | base64 --decode
hello Linux
The final newline is part of the input supplied by printf, so it is also present in the decoded result. For reproducible test data, prefer printf to an unquoted echo, whose handling of backslashes and options varies between shells.
Checkpoint: test the installed command with an expected value:
$ encoded=$(printf 'hello Linux\n' | base64 --wrap=0)
$ test "$encoded" = 'aGVsbG8gTGludXgK'
$ printf 'known-value check: %s\n' "$?"
known-value check: 0
5. Handle line wrapping deliberately
Use --wrap=COLS when another program expects a particular encoded line width. For example:
$ printf '1234567890\n' | base64 --wrap=4
MTIz
NDU2
Nzg5
MAo=
This option affects encoding output only. During decoding, ordinary newlines are accepted as part of the encoded stream. A line break inserted for display is therefore not the same thing as arbitrary junk in the input.
6. Deal with invalid or contaminated input
Decoding normally accepts Base64 characters and newlines. With --ignore-garbage, GNU base64 attempts to ignore other non-alphabet characters:
$ printf 'aGVs!bG8=\n' | base64 --decode --ignore-garbage
hello
Use this only when you understand why the extra characters are present. It can hide a damaged, truncated or incorrectly copied value. It is not a repair mechanism, and it does not make untrusted data safe to process. Without the option, an invalid character should cause you to stop and inspect the source rather than silently accepting it.
7. Avoid overwriting useful output
Shell redirection with > truncates an existing destination before base64 starts. For an output that matters, write a temporary file in the same directory, check it, then replace the destination:
$ base64 /path/to/input.bin > /path/to/input.bin.b64.new && \
cmp --silent /path/to/input.bin.b64.new /path/to/input.bin.b64 && \
mv /path/to/input.bin.b64.new /path/to/input.bin.b64
Only use that exact pattern when the old Base64 file is expected to be identical. For a new conversion, check the temporary file first, then move it explicitly:
$ base64 /path/to/input.bin > /path/to/output.b64.new && \
test -s /path/to/output.b64.new && \
mv /path/to/output.b64.new /path/to/output.b64
If the command fails, remove the incomplete .new file after checking its path. The original destination remains untouched. The mv command changes directory state, but it needs no elevated privileges when you own the directory.
Done means
base64 --versionidentifies the GNU coreutils version you are using.- The source file remains unchanged and the encoded output is saved where intended.
base64 --decoderecreates the original bytes, verified withcmp.- Line wrapping is explicit when a consuming program needs one line or a fixed width.
- You have treated Base64 as reversible encoding, not as a security boundary.