Free tool · Nothing uploaded

Base64 & URL encoder

Both directions, and — the reason this exists —correct UTF-8. A plain btoa throws on Arabic and emoji, and quietly returns a different string for an accented character. Both are fixed here.

What and which way

Decoding accepts either alphabet and adds the padding for you. Nothing is uploaded.

Result

Why so many Base64 tools break on Urdu

The browser's built-in is btoa, and it does not take text. It takes a string of characters each of which must fit in one byte — Latin-1. Two things go wrong:

  • It throws on anything above U+00FF. Arabic, Urdu, Hindi, Chinese, an emoji — "The string to be encoded contains characters outside of the Latin1 range". Loud, at least.
  • It silently lies for characters that do fit in Latin-1. btoa("café") returnsY2Fm6Q==. The correct UTF-8 answer isY2Fmw6k=. No error, no warning, a different string — and whatever decodes it as UTF-8 later gets mojibake. This is the worse failure, because nothing tells you.

The fix is one step: turn the text into UTF-8 bytes first, then Base64 the bytes. That is what every other system means by "Base64 of this string", and it is what this page does. Round-trip anything above — Urdu, an emoji, an accent — and it comes back exactly as it went in.

Decoding has a matching trap. A decoder that meets invalid UTF-8 usually substitutes replacement characters, so a wrong answer looks like a right one. This one reports the failure instead — if the Base64 holds an image rather than text, it says so.

Base64 is not encryption

Worth saying plainly, because it is a real and recurring mistake. Base64 is an encoding. There is no key. Anyone can reverse it instantly, including on this page, and every browser can do it in one line. It exists so that arbitrary bytes can travel through channels that only expect text — email attachments, data URLs, JSON fields.

Which means: a password stored Base64-encoded is a password stored in plain text with extra steps, and a token in a URL is readable by anyone who sees the URL, including every proxy and log along the way. The middle segment of a JWT is Base64 and is meant to be readable — the signature is what makes it trustworthy, not the encoding.

One more consequence: Base64 always makes things bigger, by about a third. Three bytes become four characters. That is the cost of passing through a text-only channel, and it is why inlining a large image as a data URL is usually a false economy.

encodeURI or encodeURIComponent?

The distinction that causes real bugs, so both are here as separate modes.

URL componentencodeURIComponent — escapes everything unsafe inside one piece of a URL, including/, ?, &, = and#. Use it for a value you are putting into a query string or a path segment.

Whole URLencodeURI — assumes you have handed it an entire URL and leaves those characters alone, because there they are structure rather than data.

The bug is using the second where you needed the first. A search value containing & passed through encodeURI stays a literal &, and the server reads one parameter as two. If you are building a query string, it is alwaysencodeURIComponent — and if you are not sure which you are doing, you are building a query string.

Questions

Why did another tool give me a different Base64?

Almost certainly because it used btoa on Latin-1 rather than encoding to UTF-8 first. For plain English both agree; the moment there is an accent they diverge, silently.

Can I hide a password with Base64?

No. It has no key and reverses instantly. It is an encoding, not a cipher.

Why is my output longer than the input?

Base64 turns every three bytes into four characters, so it costs about a third more. That is inherent, not a setting.

Is my text uploaded?

No. It runs in your browser — which matters, because the strings people decode here are very often tokens.

More free tools

Number base converter · JSON formatter · Colour contrast checker · Image compressor · Random picker

All free, all running entirely in your browser. Built by Maxverse Lab, a software studio in Karachi.