PercentURL / Base32 decoder

Base32 Decode Online

Paste Base32 to decode it immediately. Read UTF-8 text, inspect hexadecimal bytes, or download the exact bytes. Processing stays in your browser; Base32 is encoding, not encryption.

Paste a value to begin. Padded and unpadded input are supported.

Decode Base32 to text or bytes

  1. Paste the encoded value, not an entire URL. If it came from a query parameter, parse that parameter first so %3D becomes =.
  2. Choose the alphabet used by the sender. Base32hex is a different alphabet, not a more permissive spelling of Base32.
  3. Read the text and hex results. If the bytes are not valid UTF-8, the tool leaves the text empty and preserves the byte result.
  4. Copy valid text or download bytes. Confirm the receiving application expects those bytes before using them.

For example, MZXW6=== decodes to foo, bytes 66 6f 6f. In Base32hex the same bytes are CPNMU===. This tool does not guess the alphabet. Crockford Base32 is not supported here; see the Crockford validation guide.

What this decoder accepts and rejects

This tool accepts lowercase and omitted terminal padding as explicit compatibility choices. When padding is present, its count must match the input length. Whitespace, characters outside the selected alphabet, impossible symbol counts, and non-zero trailing pad bits are rejected. These are this tool's policies; another library may accept different inputs.

A value containing only one Base32 symbol cannot carry a complete byte. Do not add random characters to make it pass. 74====== is a different case: it decodes successfully to byte ff, which is not valid UTF-8. A text error does not mean the Base32 bytes failed to decode.

Reproducible decode checks

Run on October 25, 2026 with v24.19.0. The rows below were run against the same decoder core used above. A separate crosscheck generated 257 byte arrays of lengths 0–256 with Python's standard-library Base32 and Base32hex encoders, then checked 1,028 alphabet/padding combinations in this core. That checks these fixtures, not every possible input.

Input (standard Base32)Actual hex result or rejection
MY======66
MZXQ====666f
MZXW6===666f6f
MZXW6YQ=666f6f62
MZXW6YTB666f6f6261
MZXW6YTBOI======666f6f626172
mzxw6666f6f
74======ff
MZ======Reject: Non-zero trailing pad bits (rejected by this tool).
AReject: Invalid Base32 length.
MZXW6==Reject: Incorrect padding length.
MZX W6===Reject: Remove whitespace before decoding.
M0======Reject: Character outside the selected Base32 alphabet: 0

Get the scripts and decoder cores from the public GitHub repository. Download the replay script and decoder core into the same folder. Run node base32-decode-regression.cjs. The expected result is 13 fixtures passed; Base32hex foo passed. The recorded results include the original rejection messages.

Base32 decoding and URL parameters

Base32 padding is part of the encoded value. In ?token=MZXW6%3D%3D%3D, a query parser restores MZXW6===; the Base32 decoder then recovers foo. Do not feed the percent signs to a Base32 decoder or decode an entire URL as Base32.

Need the opposite direction? Use the Base32 encoder and padding tool. For percent escapes, use the URL decoder; for the other binary alphabet, use Base64 decode. For alphabet mix-ups, see Base32hex troubleshooting.

Format reference: RFC 4648, Base32 and Base32hex. Implementation checks dated October 25, 2026.