Home / Alt manpages / base32(1)

  • base32(1)
  • User command
  • linux

Encode and decode files safely with GNU base32

You will use GNU base32 to turn binary or text data into RFC 4648 Base32, decode it again, and check the result without casually destroying an existing file. Allow about ten minutes for the examples. You need a shell, the GNU coreutils package, and a file that you are allowed to read.

This guide describes GNU coreutils 9.4, the version installed on the machine used for these examples. The command is ordinary user-level tooling. It does not need sudo, and adding elevated privileges will not fix a bad input file or a malformed Base32 stream.

1. Check the installed command

Start by checking which binary will run and which version it reports:

$ command -v base32
/usr/bin/base32
$ base32 --version | head -n 1
base32 (GNU coreutils) 9.4

The manual page calls the program base32. With no file argument, or with - as the file, it reads standard input. It writes encoded or decoded data to standard output. That separation is useful: you can inspect the command before choosing a destination file.

Checkpoint: if command -v finds a different implementation, keep that fact in mind. Option details and error handling can differ between implementations, so do not silently assume that another program has GNU coreutils behaviour.

2. Encode a small value

Pipe data into base32 when the data is already in a command's output. The newline in this example is part of the input, so it affects the encoded result:

$ printf 'hello base32\n' | base32
NBSWY3DPEBRGC43FGMZAU===

Base32 uses letters and the digits 2 through 7, with = padding where needed. It is an encoding, not encryption. Anyone who receives the output can decode it, so do not use it as a way to conceal passwords, keys or private data.

The default output is wrapped after 76 characters. A short value does not show that behaviour, but a larger file will contain newlines inserted for readability. Those newlines are accepted during normal decoding.

3. Encode a file without overwriting it

Give the input file as the final argument and redirect standard output to a new destination:

$ base32 /path/to/input.bin > /path/to/input.bin.b32
$ test -s /path/to/input.bin.b32 && echo 'encoded output exists'
encoded output exists

The input is read, not changed. Shell redirection is the part that needs care: > truncates its destination before base32 starts. Never use the same path on both sides, such as base32 data > data, because the shell can empty the file before the program reads it.

For a destination that may already contain useful data, write to a temporary name and replace the old file only after a verification step:

$ base32 /path/to/input.bin > /path/to/input.bin.b32.new
$ test -s /path/to/input.bin.b32.new
$ mv /path/to/input.bin.b32.new /path/to/input.bin.b32

mv here changes the directory entry, not the original input. If encoding fails, remove the incomplete .new file and leave the existing output alone:

$ rm /path/to/input.bin.b32.new

Only run that removal when the path is exactly the temporary file you intended to create. Deleting a file is irreversible unless you have a separate backup.

4. Decode into a separate file

Use --decode, or its short form -d, and redirect the decoded bytes to a new path:

$ printf 'NBSWY3DPEBRGC43FGMZAU===\n' | base32 --decode
hello base32
$ base32 --decode /path/to/input.bin.b32 > /path/to/decoded.bin
$ cmp -- /path/to/input.bin /path/to/decoded.bin
$ echo "cmp status: $?"
cmp status: 0

A zero status from cmp means the original and decoded files contain the same bytes. It is a stronger check than comparing displayed text, because it also catches differences in binary data and trailing newlines.

Keep the input and output paths distinct for decoding as well. The same shell truncation rule applies to base32 --decode encoded.b32 > encoded.b32. If a destination already exists, use a .new path, run cmp or another suitable verification, then move it into place.

5. Control wrapping when producing text

Set the encoded line width with --wrap=COLS, or -w COLS. The default is 76 characters. Use zero to disable line wrapping when another system expects one continuous line:

$ printf 'hello base32\n' | base32 --wrap=0
NBSWY3DPEBRGC43FGMZAU===
$ printf 'hello base32\n' | base32 --wrap=0 | wc -l
0

The second command prints zero because the output has no terminating newline when wrapping is disabled. That is easy to miss when composing a shell pipeline or a text file. If a human will read the result, the default wrapping is usually clearer. If a protocol specifies a line length, pass it explicitly rather than relying on the default.

Line wrapping changes presentation, not the decoded bytes. Newlines are accepted by the decoder as part of the normal encoded stream.

6. Handle malformed or noisy input

During decoding, GNU base32 accepts newlines and the formal Base32 alphabet. Other non-alphabet bytes make the input invalid by default. This is a useful boundary: do not ignore unexpected data merely to make a pipeline appear successful.

$ printf 'NBSWY3DPEBRGC43FGMZAU=== garbage\n' | base32 --decode > /tmp/base32-output
base32: invalid input
$ echo "status: $?"
status: 1

The command can write some decoded bytes before reporting the problem, so do not treat a partially written destination as trustworthy. Decode to a temporary path, check the exit status, and only then publish the result. A failed decode has no automatic undo because standard output is just a byte stream.

If you have a known reason to recover data from a stream containing extra characters, add --ignore-garbage or -i:

$ printf 'NBSWY3DPEBRGC43FGMZAU=== garbage\n' | base32 --decode --ignore-garbage
hello base32

Use this option deliberately. It tells the decoder to skip non-alphabet characters; it does not prove that the skipped text was harmless, nor does it repair an incorrectly copied Base32 value. Preserve the original noisy input so you can audit what was ignored.

7. Keep the boundary clear in scripts

For a script, check the command's exit status before moving a temporary output into place. This example uses a shell conditional so the replacement only happens after successful encoding:

$ if base32 /path/to/input.bin > /path/to/input.bin.b32.new; then
>     mv /path/to/input.bin.b32.new /path/to/input.bin.b32
> else
>     rm -f /path/to/input.bin.b32.new
>     printf '%s\n' 'base32 encoding failed' >&2
> fi

For higher-assurance workflows, compare a decoded result with the original or verify a separately supplied checksum. Base32 itself provides no integrity check, authentication or secrecy. It only maps bytes to a restricted textual alphabet.

Done means

  • You confirmed that the installed command is GNU coreutils 9.4.
  • You know that input comes from a file or standard input and output goes to standard output.
  • You used separate input, temporary and final paths, so shell redirection cannot erase the source.
  • You used cmp or an equivalent check when byte-for-byte recovery mattered.
  • You set --wrap=0 only when a single output line was required.
  • You treat --ignore-garbage as a deliberate recovery choice, not a default.
  • You remember that Base32 is encoding, not encryption or integrity protection.