How to convert a ZIP to Base64
- Drop a
.zipfile on the box or pick it with the file picker. - Output as starts on Plain Base64. Use JSON if you want the file name, type and size alongside, or HTML
<a download>for a download link. - Leave Wrap at 76 off unless the string goes into a MIME email body.
- Copy output, or Save as .txt for large archives.
Zip first, then encode
Base64 adds about a third to whatever you give it. Compression takes away from text, JSON, CSV, HTML and logs before that happens, so the order matters. A small test with a 219,398-byte JSON file, an HTML page and a stylesheet:
| Approach | Characters to send |
|---|---|
| The JSON file alone, Base64-encoded | 292,532 |
| All three files zipped (19,149 bytes), then Base64 | 25,532 |
Images, videos, MP3s and existing archives are already compressed and barely shrink, but bundling them in a ZIP still turns many files into one field. For a single text payload, gzip is a lighter option; see Gzip and Base64.
Where Base64 ZIPs are used
- Deployment and automation APIs: some services that run code or host sites accept the whole package as a Base64-encoded ZIP inside a JSON request.
- CI and secret stores: a folder of certificates or config files can be zipped and stored as one Base64 secret, then restored in the pipeline with
base64 -d. - Bulk exports and attachments: a set of reports or invoices goes out in one request instead of one field per file.
Building the ZIP in code
Python can create the archive in memory and encode it without writing a temporary file:
import base64, io, zipfile
from pathlib import Path
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as z:
for path in Path("site").rglob("*"):
if path.is_file():
z.write(path, path.relative_to("site"))
package = base64.b64encode(buf.getvalue()).decode("ascii")
ZIP_DEFLATED matters: the default ZIP_STORED does not compress at all. More on streaming and line endings in Base64 in Python.
Checking a Base64 ZIP
| Base64 starts with | Meaning |
|---|---|
UEsDBBQA | ZIP whose first entry needs version 2.0 to extract, the usual case for compressed entries |
UEsDBAoA | first entry needs only version 1.0, which some tools write for uncompressed entries |
UEsFBg | an empty archive, nothing inside |
If the string starts with UEsFBg, the archive was created with no files, a frequent result of a wrong path in a build script. Base64 to ZIP decodes a string and lists the files inside, which is the quickest way to check that the archive contains what you expect.
FAQ
Why do DOCX, XLSX and JAR files also start with UEsDB?
They are ZIP archives with a fixed internal layout. UEsDB is the Base64 of PK\x03\x04, the local file header that opens every non-empty ZIP, whatever extension it has.
Does Base64 encoding compress a ZIP further?
No. Base64 makes any input about 33% larger, and a ZIP is already compressed. The gain comes from zipping first: compressible files shrink before the Base64 overhead is added.
Can I encode a password-protected ZIP?
Yes. An encrypted archive is encoded like any other file. The receiver still needs the password to extract it.