How to Decode Base64: Strings, Images, Files, and JWT Tokens
You are looking at a string that starts with iVBORw0KGgoAAAANSUhEUg or SGVsbG8sIFdvcmxkIQ== or eyJhbGciOiJIUzI1NiJ9. It might be in an API response, a database column, an email source, a configuration file, or a log entry. It is Base64-encoded data — and decoding it reveals what it actually contains. This guide shows you how to decode any Base64 string in under a minute, whether it is a string, an image, a file, or a JWT token.
iVBORw0KGgo is a PNG (those are its magic bytes, ‰PNG); /9j/ is a JPEG; JVBERi0 is a PDF (%PDF); and anything starting eyJ is JSON beginning {" — which is why every JWT starts that way. ToolPry's Base64 decoder runs natively in your browser via atob(), so even when the payload is a credential or token nothing leaves your machine. The encoding itself is defined by RFC 4648.How to Decode a Base64 String Online (Fastest Method)
For any text-based Base64 string, use ToolPry's Base64 Decoder. Paste the Base64 string into the input field, click Decode, and the decoded output appears immediately. It handles UTF-8 text, URL-safe Base64 (with - and _ instead of + and /), and automatically adds missing padding if the string length is not a multiple of 4. All processing happens in your browser — the string never leaves your device.
If your string ends with = or ==, those are padding characters — include them in the input. If the decoded output is unreadable gibberish (random bytes), the encoded data is binary (an image, PDF, or other file) rather than text — follow the image or file decoding instructions below.
How to Decode a Base64 Image
Base64 images are common in API responses, HTML files with embedded images, and CSS with data URL backgrounds. They look like long strings starting with iVBORw0KGgo (PNG) or /9j/4AAQSkZJRgAB (JPEG) or PHN2Zy (SVG). To view the image, you need to render it, not just decode the text.
Method 1: Data URL in your browser (fastest)
Open a new browser tab and paste the following into the address bar, replacing [BASE64] with your encoded string:
data:image/png;base64,[BASE64]
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Press Enter. The browser renders the image directly. Change image/png to image/jpeg, image/gif, or image/webp depending on the image type. If you do not know the type, try PNG first — it is the most common for embedded images in APIs.
Method 2: HTML file
<!-- Save as image.html and open in browser --> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="Decoded image">
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Method 3: JavaScript (save to file)
// Paste in browser console to download the decoded image
function b64toBlob(b64, mimeType) {
const bytes = atob(b64);
const arr = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) arr[i] = bytes.charCodeAt(i);
return new Blob([arr], { type: mimeType });
}
const b64 = 'iVBORw0KGgoAAAA...'; // your base64 string
const blob = b64toBlob(b64, 'image/png');
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url; a.download = 'image.png'; a.click();
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Method 4: Python (save to file)
import base64
b64_string = "iVBORw0KGgoAAAANSUhEUg..." # your base64 string
image_data = base64.b64decode(b64_string)
with open("output.png", "wb") as f:
f.write(image_data)
print("Image saved to output.png")
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
How to Decode a Base64 JWT Token
JWT (JSON Web Token) tokens have three Base64URL-encoded sections separated by dots: header.payload.signature. You can decode the header and payload to read their contents without any library — the payload contains the user claims (user ID, email, roles, expiry time).
Fastest method: browser console one-liner
// Paste in browser console — replace TOKEN with your JWT
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImVtYWlsIjoibWFyaWFAZXhhbXBsZS5jb20iLCJleHAiOjE3NDYwODY0MDB9.SflKxwRJSMeKKF';
// Decode header (part 1)
JSON.parse(atob(token.split('.')[0]));
// {alg: "HS256", typ: "JWT"}
// Decode payload (part 2) — has the actual data
const payload = JSON.parse(atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')));
console.log(payload);
// {sub: "user_123", email: "maria@example.com", exp: 1746086400}
// Check expiry
console.log('Expires:', new Date(payload.exp * 1000).toLocaleString());
console.log('Expired:', payload.exp < Date.now() / 1000);
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Understanding the JWT payload fields
| Field | Meaning | How to read it |
|---|---|---|
exp | Expiry time | Unix timestamp (seconds) — convert with Timestamp Converter |
iat | Issued at | Unix timestamp when token was created |
sub | Subject | Usually the user ID |
iss | Issuer | The authentication server that created the token |
aud | Audience | The API or service this token is for |
How to Decode Base64 in Different Languages
JavaScript (Browser)
// Standard Base64 → string
const decoded = atob('SGVsbG8sIFdvcmxkIQ==');
// "Hello, World!"
// URL-safe Base64 (JWTs use this variant)
const urlSafe = 'SGVsbG8sIFdvcmxkIQ'; // may be missing padding
const standard = urlSafe.replace(/-/g, '+').replace(/_/g, '/');
const padded = standard + '=='.slice((standard.length + 3) % 4);
const decoded2 = atob(padded);
// "Hello, World!"
// Base64 to Uint8Array (for binary data)
function b64ToBytes(b64) {
return Uint8Array.from(atob(b64), c => c.charCodeAt(0));
}
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Node.js
// Standard text decoding
const decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8');
// "Hello, World!"
// Binary file decoding
const fs = require('fs');
const b64 = fs.readFileSync('encoded.txt', 'utf8').trim();
const binary = Buffer.from(b64, 'base64');
fs.writeFileSync('output.bin', binary);
// URL-safe Base64
const urlSafe = 'SGVsbG8sIFdvcmxkIQ';
const decoded2 = Buffer.from(urlSafe, 'base64url').toString('utf8');
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Python
import base64
# Standard Base64 → string
encoded = b'SGVsbG8sIFdvcmxkIQ=='
decoded = base64.b64decode(encoded).decode('utf-8')
print(decoded) # "Hello, World!"
# URL-safe Base64 (JWTs, URLs)
url_safe = 'SGVsbG8sIFdvcmxkIQ'
# Add padding if missing
padded = url_safe + '==' * ((-len(url_safe)) % 4 or 0) # simpler: url_safe + '=='
decoded2 = base64.urlsafe_b64decode(padded).decode('utf-8')
# Decode Base64 file (image, PDF, etc.)
with open('encoded.txt') as f:
b64_string = f.read().strip()
binary_data = base64.b64decode(b64_string)
with open('output.png', 'wb') as f:
f.write(binary_data)
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Command line (Linux/Mac)
## Decode a Base64 string echo "SGVsbG8sIFdvcmxkIQ==" | base64 --decode # Hello, World! ## Decode a Base64 file to binary base64 --decode encoded.txt > output.png ## Decode URL-safe Base64 (replace - with + and _ with /) echo "SGVsbG8sIFdvcmxkIQ" | tr -- '-_' '+/' | base64 --decode
Tested: Node.js 22.x, Python 3.12.4, Chrome 125. Output may vary on older runtimes.
Common Base64 Decoding Errors and Fixes
Invalid character in Base64 string
Standard Base64 uses A–Z, a–z, 0–9, +, and /. URL-safe Base64 uses - and _ instead. If your string contains - or _ and decoding fails, convert them: replace - with + and _ with / before decoding with the standard decoder. If your string contains spaces or newlines (common in MIME email attachments), strip them first.
Incorrect padding
Base64 strings must have a length divisible by 4. If the string length mod 4 is not 0, add = padding characters until it is. A string of length 22 needs 2 padding characters (==). A string of length 23 needs 1 (=). Most decoders handle this automatically, but some strict implementations reject incorrectly padded strings.
Decoded output is binary garbage
The encoded data is binary (an image, PDF, compressed file, or other non-text format), not a text string. Do not try to decode it to a string — decode it to raw bytes and save as a file. Use the image decoding method above if you think it is an image, or save with a generic extension like .bin and check the file type with a hex editor or file output.bin on Linux.
Base64 Decoding FAQ
Is Base64 decoding safe? Can it contain viruses?
Decoding Base64 itself is safe — it is just a format conversion. The decoded data could contain anything, including malicious executable files. Never execute decoded binary data from untrusted sources. If you decode a Base64 string and save it as a file, treat it with the same caution as any downloaded file from the internet.
How do I know if a string is Base64 encoded?
Base64 strings only contain letters, digits, +, /, and = (or - and _ for URL-safe). They typically end with one or two = padding characters. Their length is always a multiple of 4 (or would be with padding). They look like random text with no spaces or punctuation besides the characters above. If a string matches these patterns, it is likely Base64 — try decoding it with ToolPry's Base64 Decoder to confirm.
What is the difference between Base64 and Base64URL?
Base64URL replaces + with - and / with _, and omits = padding. It is used in JWTs, OAuth tokens, and anywhere the Base64 string appears in a URL. Standard Base64 uses + and /, which have special meanings in URLs. If you are decoding a JWT or any token from a URL, use URL-safe Base64 decoding.
The Bottom Line
Decoding is instant and lossless — the only real gotchas are URL-safe characters (-/_) and missing padding. Paste the string into the ToolPry Base64 decoder and switch on the URL-safe option for JWTs and tokens; if the output is binary garble rather than readable text, you are decoding an image or file — save it to disk instead of reading it as a string.