HCODX / Base64 Converter
100% browser-based · UTF-8 safe · standard & URL-safe

Base64 Encoder & Decoder

Encode and decode text, files, and images using Base64. Proper UTF-8 handling for Unicode strings, single-pass file encoding (no chunked-padding bugs), and a structural validator for inspecting unfamiliar Base64 payloads.

Plain text / Base64
Result
Options
Bytes the text is encoded into before Base64.
URL-safe replaces + and /.
Input chars
0
Input bytes
0 B
Output chars
0
Output bytes
0 B
Encode a file to Base64
Drop a file here
or click to browse — any file type, any size
Encoded output
Decode Base64 to a file
Base64 / data URI
Extension is auto-suggested from data-URI MIME when present.
Base64 input
Analysis
Paste a Base64 string above
    Example

    Round-trip text in a couple of clicks

    UTF-8-safe by default, so emoji and non-ASCII characters survive the round trip cleanly.

    Input text
    Hello, 世界! 🌍
    This is a Base64 round-trip test.
    Standard Base64
    SGVsbG8sIOS4lueVjCEg8J+MjQpUaGlzIGlzIGEgQmFzZTY0IHJvdW5kLXRyaXAgdGVzdC4=
    Use cases

    Built for everyday API & web work

    From inspecting a JWT to inlining an icon, Base64 shows up in surprising places.

    Auth & tokens

    Inspect HTTP Basic credentials, or peek at a JWT payload without fetching a verification library.

    Inline data URIs

    Convert tiny SVGs and icons to data:image/...;base64, for use directly in HTML or CSS.

    Email & MIME

    Generate MIME-style 76-character-wrapped Base64 for email attachments and signed messages.

    URL-safe payloads

    Produce Base64 that fits inside URLs and filenames — no +, no /, optionally no padding.

    Forensics & debugging

    Validate suspicious strings, see why atob rejects them, and recover binary blobs from logs or tickets.

    Embedding binary blobs

    Stash small binaries (PNGs, fonts, certs) as text in JSON or YAML configs without a separate asset pipeline.

    Step by step

    How to encode and decode Base64

    Pick a tab, drop content in, choose options, hit the button. Everything runs locally.

    1

    Choose your input type

    Use the Text tab for strings, the Files tab for binary uploads, or the Validator tab to inspect a Base64 string you found.

    2

    Pick a variant

    Standard Base64 is the default — it's what you want for email, JSON payloads, and most APIs. Switch to URL-safe if the result needs to fit in a URL or filename.

    3

    Encode or decode

    The Text tab has separate Encode and Decode buttons. The Files tab encodes on upload and decodes via the Decode & download button.

    4

    Copy or download

    Use the toolbar icons on each editor to copy to the clipboard or save the result as a file. The decoder also auto-detects MIME from data URIs and suggests a filename extension.

    FAQ

    Frequently asked questions

    Everything worth knowing about Base64.

    Base64 represents arbitrary binary data using only 64 printable ASCII characters: A–Z, a–z, 0–9, plus two extras (+ / for standard, - _ for URL-safe).

    It's used wherever a text-only channel must carry binary payloads:

    • Email attachments (MIME)
    • Data URIs for inline images / fonts
    • JWT tokens and HTTP Basic credentials
    • Embedding binary in JSON, YAML, XML, env vars

    The trade-off: the encoded output is roughly 33% larger than the input.

    Standard (RFC 4648 §4) — uses + and /. The right choice for email, most APIs, and anywhere the output isn't going to land in a URL.

    URL-safe (RFC 4648 §5) — replaces + with - and / with _ so the encoded string can sit inside a URL path, query string, or filename without further escaping. Padding (=) is often dropped for the same reason.

    The validator on this page detects which variant you have automatically.

    Base64 packs 3 bytes into 4 characters. When the input length isn't a multiple of 3, padding = characters are appended so the output length is a multiple of 4.

    • Input length mod 3 = 0 → no padding
    • Input length mod 3 = 1 → == at the end
    • Input length mod 3 = 2 → = at the end

    You'll never see more than two = characters, and they're always at the end.

    Wrap the Base64 in a data URI:

    <img src="data:image/png;base64,iVBORw0KGgo…" alt="" />
    .icon { background-image: url(data:image/svg+xml;base64,PHN2…); }

    Toggle Data URI prefix on the Files tab to get the prefix included automatically. Use sparingly — inline data inflates the document and bypasses asset caching.

    Base64 encodes raw bytes, not characters. To Base64 a string, you first need a byte representation of it.

    JavaScript's built-in btoa() only works on strings whose characters all fit in a single byte (Latin-1). Calling btoa("日本") throws.

    This tool uses TextEncoder to convert your text to UTF-8 bytes first, so emoji and non-Latin scripts round-trip cleanly. If you specifically need ASCII-only output, switch the charset selector and the tool will refuse non-ASCII input rather than silently mangling it.

    Yes. The encoder reads the entire file into memory once and produces Base64 in a single btoa() call (with the binary string built up via String.fromCharCode on 32 KB slices to avoid call-stack limits).

    This deliberately avoids the common bug where chunked encoders call btoa on each chunk separately — if a chunk size isn't a multiple of 3, every chunk's output ends in == padding, corrupting the final string with mid-stream = characters.

    Practical limit is whatever your browser and machine can hold in memory — comfortably hundreds of megabytes on a modern laptop.

    No. Every operation runs in your browser, in JavaScript. Your text and files never leave your machine.

    atob() is strict — it rejects whitespace, the URL-safe alphabet, and inputs whose length isn't a multiple of 4 with proper padding.

    This tool's decoder is forgiving: it strips whitespace, maps -+ and _/, and re-pads to a multiple of 4 before calling atob. The validator tab tells you exactly which rule a problematic string violates.

    About

    About Base64

    Base64 is one of the oldest binary-to-text encoding schemes still in active use. It was standardized as part of MIME in RFC 2045 (1996) and refined as a standalone format in RFC 4648 (2006).

    How it works

    Three bytes (24 bits) of input are split into four 6-bit groups. Each 6-bit group is then mapped to one of 64 characters in the alphabet. When the input doesn't divide evenly into 3-byte groups, the encoder pads the final group with zero bits and appends = characters to mark the padding.

    That's why Base64 is roughly 33% larger than the raw bytes — 4 output characters for every 3 input bytes, ignoring padding.

    Variants you'll encounter

    • Standard (RFC 4648 §4) — alphabet is A–Z a–z 0–9 + / with = padding. Email, most APIs.
    • URL-safe (RFC 4648 §5) — same idea but +- and /_. Padding is often omitted. Used in JWTs, OAuth, URLs, filenames.
    • MIME variant (RFC 2045) — standard alphabet, but lines are wrapped at 76 characters. Required for SMTP transport.
    • OpenSSL / PEM — standard alphabet wrapped at 64 characters, used in PEM-encoded certificates and keys.
    • Modified Base64 for filenames — niche variants like Base64URL but with different padding rules; still falls under RFC 4648 §5.

    What Base64 isn't

    • Encryption. Base64 is fully reversible without a key. Don't confuse it with security.
    • Compression. Base64 is always larger than the input. Compress first, then Base64.
    • A canonical format. Two encoders may produce different outputs for the same bytes — different variants, different line wrapping, with or without padding. The decoder needs to be forgiving.

    Tips

    • For network payloads, prefer raw bytes (e.g. multipart/form-data) over Base64 when you control both ends — you avoid the 33% size hit.
    • For embedded images, only use data URIs for assets small enough that the inlining win beats the cache miss (typically < 1 KB).
    • JWT payloads use URL-safe Base64 without padding. Strip the = after standard encoding, or just toggle the option here.
    • If a string fails to decode, run it through the Validator — the issue is almost always invisible whitespace, a URL-safe character mixed with standard, or a missing/extra =.