Base64 Decode & Encode: to PDF, Image or Any File

Paste Base64 and get the file back, whether it is a PDF, an image, text or a JWT, or drop a file to Base64 encode it. Everything happens in this tab.

33 file formats read from their own bytes · RFC 4648 · nothing is uploaded
Encoded

Paste something above, drop a file on the card, or press one of the examples.

Try

Everything stays in this tab: nothing you paste or drop is uploaded, and decoded HTML or script is shown as text, never run.

3 bytes → 4 characters
Example: Man
M77 · 4DByte 1
a97 · 61Byte 2
n110 · 6EByte 3
1922546

Three bytes are 24 bits. Base64 cuts the same 24 bits into four groups of six, and each group names one of 64 characters. The white lines are where the bytes end: they do not line up with the groups, and that is the whole trick.

Character 1

16 + 2 + 1 = 19 T

Index 19 in the standard alphabet.

1where a byte endsadded, not yoursdifferent in URL-safePoint at a character to see its six bits add up.

How to use the Base64 decoder and encoder

This Base64 converter works both ways: paste anything into the one field (text, Base64, a whole data: URI or a JWT), or press Choose a file or drop one onto the card. The tool works out which way round it is, says so in the pill, and keeps the other reading one click away.

Decoding Base64 to text or to a file, you get the type read from the bytes themselves, the size, an image's pixel size, a Preview of an image or a PDF, and a download with the right extension. Encoding one, you get the Base64, a ready data: URI and what the encoding cost in size. The Alphabet, Padding and Line breaks options under the result change the output.

Base64 decoder: a pasted Base64 string decoded to a PDF document, with its type, size and the 3-bytes-to-4-characters figureBase64 decoder: a pasted Base64 string decoded to a PDF document, with its type, size and the 3-bytes-to-4-characters figureOne field, both waysPaste text, Base64, a data: URI or a JWT. The pill says how it was read; the menu changes it.Choose a fileOr drop one anywhere on the card: it becomes Base64 and a data: URI, without leaving the tab.What the bytes areDecoding, the result opens with the file's type, size and signature, then a preview and a download.Output optionsStandard or URL-safe alphabet, padding on or off, and lines wrapped for MIME or PEM.3 bytes → 4 charactersYour own bytes, re-cut into groups of six. Point at a character to see its bits add up.
The tool decoding a PDF. Select a number to see what each part does.

What is Base64, and why does it exist?

Base64 writes any bytes using 64 characters that survive anywhere: A–Z, a–z, 0–9, + and /. It exists because email, URLs, JSON and XML were built for text, and a raw byte can be a control code, a quote mark or a null that breaks them.

It takes three bytes at a time, lays their 24 bits in a row and cuts the row into four groups of six. Six bits hold 64 values, so each group names exactly one character. Three bytes in, four characters out, every time: that is why Base64 is about a third bigger than what went in.

Man → TWFu
M77 · 4DByte 1
a97 · 61Byte 2
n110 · 6EByte 3
1922546TWFu

Three bytes are 24 bits. Base64 re-cuts them into four groups of six, and each group names one of 64 printable characters, so three bytes always cost four characters. That is where the 33% growth comes from.

Ma → TWE=
M77 · 4DByte 1
a97 · 61Byte 2
no byte—Byte 3
19224—TWE=

Two bytes are 16 bits. Base64 adds 2 zero bits to finish the third group, and one = stands where the fourth character would be.

M → TQ==
M77 · 4DByte 1
no byte—Byte 2
no byte—Byte 3
1916——TQ==

One byte is 8 bits. Base64 adds 4 zero bits to finish the second group, and two = stand where the third and fourth characters would be. = carries no bits at all.

The white lines mark where one byte ends and the next begins. They do not line up with the groups of six, and that offset is the whole mechanism. Source: RFC 4648 §4

How do I decode Base64 to a PDF?

Paste the string and the tool rebuilds the PDF: it shows the version and the size, opens the document in your browser's own PDF viewer and gives you a download. You don't have to say it is a PDF, and you don't have to remove a data: prefix first.

A PDF is recognised by its first five bytes, %PDF-, so the file is identified even when its name, the type the sender claimed or the field it came in say otherwise. If the bytes are not a PDF, the page says what they are instead of failing to open a document that was never there.

The file is rebuilt in your browser. Nothing is uploaded, which matters when the PDF is a payslip, a contract or an invoice.

JSON from an API"document": "JVBERi0xLjcKJeLjz9MKMS…"A field in a response. The quotes are not part of the Base64.
An email attachmentContent-Transfer-Encoding: base64MIME wraps the body at 76 characters a line. Paste it with the line breaks: they are skipped.
A data: URIdata:application/pdf;base64,JVBERi0x…Paste the whole thing. The prefix is read, not stripped by hand.
The first bytes say what it is
  1. 25%
  2. 50P
  3. 44D
  4. 46F
  5. 2D-
  6. 311
  7. 2E.
  8. 377

The first 5 bytes, %PDF-, are the whole signature. Bytes 6 to 8 are the version: 1.7. No file extension is involved, so a PDF someone named .txt still comes back as a PDF.

Three places people copy a Base64 PDF from, and the bytes that identify it once it is decoded. Source: ISO 32000-1:2008 §7.5.2, RFC 8118 §8

How do I convert an image to Base64, and when should I?

Drop the image and you get its Base64 and a ready data: URI to paste into HTML or CSS. Whether you should is the harder question: Base64 always costs about a third more, and an inline image can't be cached on its own.

Going the other way, Base64 to image, you get the format, the size and the real pixel size read from the file's own header, not from the picture on screen, and a download with the right extension.

  • The file on disk12.9 kB 100%
  • As Base6417.3 kB +33.4%
  • Wrapped at 76 characters for MIME17.5 kB +35.1%
  • The file, gzipped11.7 kB -9.5%
  • The Base64, gzipped12.5 kB -3.2%
A real file
  • downloaded once
  • cached by the browser and the CDN
  • fetched beside the page, not inside it
The same image inline
  • a third bigger before compression
  • cached only as part of the file that holds it
  • parsed as part of the stylesheet or the HTML

Compression wins most of it back: gzipped, the Base64 is only 7% bigger than the gzipped file. What it cannot give back is the image's own cache entry: inlined in an HTML page, it is downloaded again with every page that carries it.

The rule of thumb: inline a few hundred bytes (an icon, a spacer, a logo in an email) and link anything bigger. This 12.9 kB PNG image is already past the line.

Measured on the image the tool's example decodes: the same bytes, carried five ways, gzipped at the highest level. Source: RFC 2045 §6.8

Base64 vs URL-safe Base64: what is the difference?

URL-safe Base64 (RFC 4648 §5) is the same encoding with two characters swapped: + becomes - and / becomes _. The padding is often left off as well.

Use it wherever the result goes into a URL, a file name or a cookie. JSON Web Tokens use it throughout, which is why the parts of a token never end in =. This tool reads both alphabets and tells you when one string carries both.

Standard (RFC 4648 §4)+/8=
URL-safe (RFC 4648 §5)-_8=
base64url in a JWT (RFC 7515 §2)-_8
  • + → -Index 62. In a query string, a form decoder reads + as a space, so the data comes back wrong.
  • / → _Index 63. In a path, / starts a new segment, so the value is split in two.
  • = droppedIn a URL, = is usually percent-encoded as %3D (RFC 4648 §5). A JWT drops it altogether (RFC 7515 §2): the length alone says where the bytes end.

The first 62 characters of the two alphabets are identical, which is why a tool that reads both alphabets can decode either, and why this page tells you when a string carries both.

Only 2 characters differ between the two alphabets. Everything else about them is the same. Source: RFC 4648 §5, RFC 7515 §2

Is Base64 encryption? No.

Base64 hides nothing. There is no key and no secret, and reversing it takes no effort at all: a decoder like this one does it as you type.

HTTP Basic authentication is where this matters most: the header carries the user name and password as one Base64 string, readable by anyone who sees it, which is why RFC 7617 counts the scheme as secure only over an encrypted connection such as TLS. If something must stay unreadable, it needs encryption. Base64 only gets bytes safely through a channel built for text.

An Authorization header, as RFC 7617 §2 builds it

Authorization: Basic dXNlcjpwYXNzd29yZA==

One step back: no key needed, no password needed

user:password

RFC 7617 builds the header step by step, and the last step is the whole of its “protection”: the client “obtains the basic-credentials by encoding this octet sequence using Base64”. Its §1 says what that means: unless TLS or a similar system protects the connection, “the user-id and password are passed over the network as cleartext”. Base64 has no key, so there is nothing to break: anyone who has the string has the password.

The credentials above are made up. Reading them back takes one step and no key: that is what “encoding, not encryption” means. Source: RFC 7617 §2, §1

Why does my decoded text look like mojibake?

Because Base64 carries bytes, and bytes only become letters once something picks a character encoding. Read UTF-8 text as if it were ISO-8859-1 and é turns into é; read ISO-8859-1 as UTF-8 and it becomes a replacement mark.

A data: URI can declare its charset, and this page reads the text in that charset instead of forcing everything through UTF-8. When your browser has no decoder for the declared one, the page says so rather than quietly showing you the wrong letters.

“Café” written in UTF-8436166C3A9
“Café” written in ISO-8859-1436166E9

In UTF-8, é is 2 bytes; in ISO-8859-1 it is 1 byte. Base64 carries bytes, not letters, so the string itself cannot tell a decoder which was meant.

Read the right wayCafé
UTF-8 bytes read as ISO-8859-1Café
ISO-8859-1 bytes read as UTF-8Caf�
Mojibake has two shapes: readable nonsense (Café) when UTF-8 is read as a single-byte code page, and a replacement mark (Caf�) when the bytes are not valid UTF-8 at all. Source: RFC 4648 §4, RFC 2397 §4

Base64 in Python, JavaScript, Java, C#, Go, PowerShell and the shell

Every language has Base64 built in. The traps are the same everywhere: encode bytes, not a string, and say which character encoding the text is in.

JavaScript's btoa() is the sharpest edge: it only takes characters up to U+00FF, so anything beyond Latin-1 has to become UTF-8 bytes with TextEncoder first. Each example below encodes and decodes “Man” and was run to check its output.

import base64

b64 = base64.b64encode("Man".encode("utf-8")).decode("ascii")
print(b64)                                    # TWFu
print(base64.b64decode(b64).decode("utf-8"))  # Man

Run with Python 3.14.4 on October 26, 2026: it prints what the comments show.

Every snippet was run on “Man” and prints what its comments show. The shell's base64 -d is -D on older macOS. Source: gnu.org, developer.mozilla.org

The Base64 alphabet, 0 to 63

Each group of six bits is a number from 0 to 63, and this is the table it is looked up in. Base64 is case-sensitive: A is 0 and a is 26, so changing a letter's case breaks the string.

It is worth knowing by sight: a run of As is a run of zero bytes, and a Base64 string that starts with JVBER is a PDF, iVBOR a PNG and /9j/ a JPEG.

  1. A0
  2. B1
  3. C2
  4. D3
  5. E4
  6. F5
  7. G6
  8. H7
  9. I8
  10. J9
  11. K10
  12. L11
  13. M12
  14. N13
  15. O14
  16. P15
  17. Q16
  18. R17
  19. S18
  20. T19
  21. U20
  22. V21
  23. W22
  24. X23
  25. Y24
  26. Z25
  27. a26
  28. b27
  29. c28
  30. d29
  31. e30
  32. f31
  33. g32
  34. h33
  35. i34
  36. j35
  37. k36
  38. l37
  39. m38
  40. n39
  41. o40
  42. p41
  43. q42
  44. r43
  45. s44
  46. t45
  47. u46
  48. v47
  49. w48
  50. x49
  51. y50
  52. z51
  53. 052
  54. 153
  55. 254
  56. 355
  57. 456
  58. 557
  59. 658
  60. 759
  61. 860
  62. 961
  63. +URL-safe: -62
  64. /URL-safe: _63

0–25 are A–Z, 26–51 are a–z, 52–61 are 0–9. Only the table's last two characters differ between the two alphabets, marked above. = is not in the table at all: it is not a value, it is the mark that says the last group of three bytes was short.

The 64 characters, in the order RFC 4648 §4 gives them. The number under each one is the six-bit value it stands for. Source: RFC 4648 §4

Base64: questions and answers

What is a Base64 decode?

Decoding Base64 turns each group of four characters back into the three bytes it stands for. Those bytes may be text, or a whole file such as a PDF, a PNG image or a ZIP archive. This tool reads the first bytes to tell which, then shows you the text or the file itself rather than a screen of symbols, and lets you download it.

How do I decode a Base64 file?

Paste the Base64 string into the field. The tool decodes it, checks the first bytes against the file signatures it knows (33 file formats in all), names the format, previews an image or a PDF, and gives you a download with the right extension. You never have to say what kind of file it is, and nothing is uploaded to find out.

What is Base64 used for?

It carries bytes through places built for text: email attachments (MIME), data: URIs in HTML and CSS, binary fields in JSON and XML, JSON Web Tokens, HTTP Basic authentication, and certificates and keys in PEM files. In each case the data has to pass through a channel that might change or drop raw bytes, so it travels as plain letters and digits.

Is Base64 encryption?

No. Base64 is an encoding, not a cipher: it has no key and no secret, and anyone can reverse it in a moment, as this page does while you type. Treat anything written in Base64 as if it were in plain sight. If data has to stay private, encrypt it first, then encode the encrypted bytes as Base64 if they must travel as text.

Is it safe to decode Base64 online?

On this page, yes, and you can check it: everything is decoded by JavaScript in your own browser tab and nothing you paste or drop is uploaded. Decoded HTML, SVG and scripts are shown as text, never run; an image or a PDF is shown by your browser's own viewer. Open the network tab of your browser's developer tools while you use it: no request carries your data.

Why is Base64 33% bigger than the original?

Because every three bytes become four characters, and four divided by three is 1.33. Up to two = padding characters can be added at the end, and wrapping lines at 76 characters for email adds a line break to every line, so a long string is often about 35% bigger than the bytes it carries. Compression such as gzip wins most of that back.

What is URL-safe Base64?

It is Base64 with + replaced by - and / replaced by _, as RFC 4648 §5 defines it, so the result can go into a URL, a file name or a cookie without being escaped. The padding is usually dropped too, as in JSON Web Tokens. This tool reads both alphabets, even mixed in one string, and can write either one.

Why does my Base64 decode fail?

Almost always because of one character that is not in the Base64 alphabet: an ellipsis where a chat app cut the string, a curly quote from a word processor, or a non-breaking space from a PDF. This tool names the character, shows it where it sits with its position, tells you how much decoded cleanly before it, and offers to remove it when what is left can still be decoded.

Can I convert Base64 to an image?

Yes. Paste the string, with or without a prefix such as data:image/png;base64,, and the image appears with its format, its size and its real pixel size, read from the file's own header. Then download it with the right extension. PNG, JPEG, GIF, WebP, BMP, ICO and AVIF are previewed; an SVG is shown as text first, because an SVG can carry script.

What does the = at the end of Base64 mean?

It means the last group of three bytes was short. Two leftover bytes become three characters and one =, and one leftover byte becomes two characters and ==. The padding carries no data at all: it only tells a decoder where the bytes end. Many decoders, this one included, also read Base64 whose padding was left off.

Is there a size limit?

A file you choose or drop can be up to 10 MB; a bigger one is refused with its name and size, never half read. The limit for pasted text is 14,349,002 characters: enough for the Base64 of a 10 MB file with its line breaks, so anything the tool encodes can be decoded again. Large inputs are read in the background, so typing stays smooth.

Can I decode a JWT here?

Yes. Paste the token and its header and payload are printed as formatted JSON, with dates shown beside the iat and exp claims and the signature shown as bytes. This page only decodes the three base64url parts: it does not verify the signature and never says a token is valid, so don't use it to decide whether to trust one.

Missing something?Suggest a feature or a new tool