Base64 + Gzip Decoded — How to Handle Compressed Base64 Strings
Table of Contents
If you have encountered a Base64 string that decodes to garbled binary output instead of readable text, it is likely compressed — gzip, deflate, or zlib compression applied before the Base64 encoding. This is a two-step encoding: compress the data, then Base64-encode the compressed bytes.
Our Base64 encoder/decoder handles the Base64 step. This guide explains the full picture — what this combination is, where it appears, and how to decode it completely.
Why Base64 + Gzip Exists — The Compression + Transport Problem
Base64 encoding alone makes binary data safe for text-based transmission but adds 33% overhead. For large payloads — SAML assertions, compressed JWT tokens, bundled configuration — developers first compress the data with gzip (which typically reduces size by 60-80%), then Base64-encode the compressed bytes for safe transport.
Net result: a 10KB string becomes ~3KB gzip output, which becomes ~4KB Base64. Compared to raw Base64 of the original 10KB (which would be 13.3KB), the compress-then-encode approach is about 70% smaller.
Where you encounter this combination:
- SAML AuthnRequests and Responses — SAML 2.0 redirect binding compresses XML with DEFLATE, then Base64-encodes it. This is specified in the SAML standard.
- AWS CloudFront policies — bucket policies and signed URL parameters are gzip-compressed and Base64-encoded.
- Some API payloads — APIs serving large JSON responses sometimes compress and Base64-encode them for transport.
- Kubernetes ConfigMaps and Secrets — occasionally compressed before Base64 encoding when the raw content is very large.
Step 1 — Identify Whether It Is Gzip, Deflate, or Zlib
After Base64-decoding (using our free tool), the result will be binary bytes. The first bytes identify the compression format:
| Format | Magic Bytes (hex) | Recognizable As |
|---|---|---|
| Gzip | 1F 8B | Decoded string starts with garbled chars roughly matching these bytes |
| Zlib/Deflate | 78 9C or 78 DA or 78 01 | SAML most commonly uses raw DEFLATE (no header) |
| Plain text | Any printable chars | Readable immediately after Base64 decode — no compression |
SAML 2.0 redirect binding specifically uses raw DEFLATE (no gzip wrapper, no zlib header) — this is why SAML decoders are separate from general Base64+gzip decoders. If you are decoding a SAML request, use a dedicated SAML decoder tool.
Sell Custom Apparel — We Handle Printing & Free ShippingDecoding Base64 + Gzip in the Browser (JavaScript)
Browser JavaScript can handle gzip decompression using the Compression Streams API (available in Chrome 80+, Firefox 113+, Safari 16.4+):
async function decodeBase64Gzip(base64String) {
// Step 1: Base64 decode to bytes
const binaryString = atob(base64String);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// Step 2: Decompress using Compression Streams API
const stream = new DecompressionStream('gzip');
const writer = stream.writable.getWriter();
writer.write(bytes);
writer.close();
// Step 3: Read decompressed output as text
const reader = stream.readable.getReader();
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
}
const result = new TextDecoder().decode(
new Uint8Array(chunks.flatMap(c => [...c]))
);
return result;
}
// Use it:
decodeBase64Gzip("H4sIAAAAAAAAA...").then(console.log);
For deflate (SAML), replace 'gzip' with 'deflate-raw' in the DecompressionStream constructor.
Command Line — Decode Base64 + Gzip on Linux and Mac
The command line combines Base64 decoding and gzip decompression in a pipeline:
# Decode Base64 then decompress gzip echo "H4sIAAAAAAAAA..." | base64 -d | gunzip # Or using gzip -d instead of gunzip echo "H4sIAAAAAAAAA..." | base64 -d | gzip -d # For deflate/zlib (not gzip) — needs Python or openssl echo "eJzLSM3..." | base64 -d | python3 -c " import sys, zlib sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read())) " # Save to file instead of printing echo "H4sIAAAAAAAAA..." | base64 -d | gunzip > output.txt
On Mac, note that the built-in base64 command uses -D (capital D) for decode, not -d. Replace base64 -d with base64 -D on macOS.
Python and Node.js — Full Decode Function
Python:
import base64
import gzip
import zlib
# Decode Base64 + gzip
def decode_base64_gzip(encoded: str) -> str:
compressed = base64.b64decode(encoded)
return gzip.decompress(compressed).decode('utf-8')
# Decode Base64 + zlib/deflate
def decode_base64_zlib(encoded: str) -> str:
compressed = base64.b64decode(encoded)
return zlib.decompress(compressed).decode('utf-8')
# Decode Base64 + raw deflate (SAML)
def decode_base64_deflate_raw(encoded: str) -> str:
compressed = base64.b64decode(encoded)
return zlib.decompress(compressed, -15).decode('utf-8')
# The -15 wbits value tells zlib to use raw deflate (no header)
Node.js:
const zlib = require('zlib');
const { promisify } = require('util');
const gunzip = promisify(zlib.gunzip);
const inflate = promisify(zlib.inflate);
const inflateRaw = promisify(zlib.inflateRaw);
async function decodeBase64Gzip(encoded) {
const compressed = Buffer.from(encoded, 'base64');
const decompressed = await gunzip(compressed);
return decompressed.toString('utf-8');
}
async function decodeBase64DeflateRaw(encoded) {
const compressed = Buffer.from(encoded, 'base64');
const decompressed = await inflateRaw(compressed);
return decompressed.toString('utf-8'); // for SAML
}
Try It Free — No Signup Required
Runs 100% in your browser. No data is collected, stored, or sent anywhere.
Open Free Base64 Encoder/DecoderFrequently Asked Questions
How can I tell if a Base64 string is compressed?
Decode it with a standard Base64 decoder. If the output is readable text, it was not compressed. If the output is garbled binary characters, it is likely compressed. The specific garbled pattern reveals the compression format: gzip output starts with bytes 0x1F and 0x8B.
What is the difference between gzip, deflate, and zlib?
All three use the DEFLATE compression algorithm. Gzip adds a file header and CRC checksum. Zlib adds a smaller header. Raw DEFLATE has no header at all. When someone says "deflate" they sometimes mean raw DEFLATE and sometimes mean the zlib-wrapped version — which one depends on the specific standard or API.
Can I use the free Base64 decoder for the Base64 step?
Yes — paste the encoded string into the free decoder to confirm it produces binary output (which appears as garbled characters). That confirms it is Base64, and the garbled output is the compressed data. The second step (decompression) requires one of the code approaches above or a dedicated tool.

