ToyTools Guide
How to Identify an Unknown String Encoding
Learn to tell Base64 from hex, spot the URL-safe alphabet, recognise a double-encoded value, and know when a string is not encoded at all.
Quick Answer
Here is how to identify an unknown encoded string, and how to answer what encoding is this for a value you were handed: check three things in order, which characters it uses, how long it is, and what it produces when you decode it. The alphabet rules most candidates out at a glance, the length kills the rest, and only a decode that returns readable text proves the answer. That three-step sequence is encoding detection, and it is the whole method.
That is also how you tell Base64 from hex, which is the question people arrive with most. Work through it by hand and you will identify base64 or hex in about a minute. The encoding detector runs all three checks against every codec at once and shows you what each reading decodes to, so you choose the one that produced something meaningful instead of guessing.
Try The Encoding Detector →How encoding detection works
Every text encoding restricts itself to a fixed alphabet, and that restriction is the first
filter. Hex uses only 0-9 and a-f. Binary uses only 0
and 1. Percent-encoding is ordinary text sprinkled with % followed
by two hex digits. Base64 draws on A-Z, a-z, 0-9 plus
+ and /, with = padding the end.
So a single uppercase letter rules out hex, and a + or a trailing =
points hard at Base64. However, the alphabet never settles it alone, because the sets overlap:
decade is valid hex, and almost every lowercase English word is a valid Base64
fragment. A detector that stopped here would name an encoding for ordinary prose, which is
worse than saying nothing.
Length is the second filter, and it is unforgiving. Hex encodes one byte as exactly two characters, so a hex string always has an even length. Base64 encodes three bytes as four characters, so a complete Base64 string is a multiple of four. Binary is a multiple of eight. Therefore a string of 37 characters is none of the three, whatever alphabet it matches.
The decode is the third filter and the only one that proves anything. Each surviving candidate is actually decoded, and the result is scored on how much of it is printable. A reading that produces control characters and replacement markers is discarded; one that produces a sentence is reported with high confidence. This is why the tool can detect string encoding without ever being told what to expect.
The URL-safe alphabet, and why decoders reject valid strings
Base64 has a second alphabet. Standard Base64 uses + and /, but both
carry meaning inside a URL: / separates path segments and + has
historically meant a space in query strings. RFC 4648 therefore defines a URL-safe variant
that substitutes - for + and _ for /, and
drops the padding entirely in most token formats.
This is the answer to why does my base64 decode to gibberish, which is the
single most common reason a valid string appears to be broken. A standard decoder handed a
Base64URL value either refuses it outright or, worse, produces the wrong bytes quietly. JWTs,
OAuth tokens and signed URLs all use the URL-safe alphabet, so anything copied out of a
browser address bar is a strong candidate. So when you are asking is this
base64url, the test is simple: if the string contains - or
_ but never + or /, read it as Base64URL first.
Missing padding is the related case. A Base64 value whose length leaves a remainder of two or
three when divided by four lost its = characters somewhere in transit, and adding
them back makes it decode correctly. A remainder of one cannot be repaired, because no amount
of padding produces a whole number of bytes.
How to decode a double-encoded value
A value that travelled through a URL is routinely encoded twice. A Base64 token placed into a query string gets percent-encoded on top of its existing encoding, so decoding the percent-encoding hands back Base64 rather than readable text. The result looks exactly like corrupt data, and this is where most people stop and conclude the value is damaged.
The fix is to treat the decode as a loop rather than a single step. Take the decoded output and run the same alphabet and length checks on it again. If it still matches a codec cleanly, it was wrapped twice, not broken, so decode it again and repeat until the result is text a person can read. Stop when no codec matches, because that is either the answer or a sign the payload was never text to begin with.
The detector runs that loop for you and says so explicitly when another layer is present, which is the difference between an answer and a dead end.
Examples
Example 1, a single layer. SGVsbG8sIFdvcmxkIQ== uses the
standard Base64 alphabet, its length is a multiple of four, and it ends in ==.
Decoding gives Hello, World!, which is readable text, so the answer is settled at
the first attempt.
Example 2, the URL-safe trap. PDw_Pj4_ contains an underscore
and no + or /. A standard decoder rejects it. Read as Base64URL, the
underscore becomes / and it decodes cleanly. Nothing was wrong with the string.
Example 3, three layers. Take
SGVsbG8lMkMlMjBXb3JsZCUyMQ%3D%3D, the sample on the tool. The %3D
sequences say something percent-encoded it, so that is the outer layer. Decoding gives
SGVsbG8lMkMlMjBXb3JsZCUyMQ==, which is not readable, and this is the point where
the trail goes cold for most people. Run the checks again: Base64 alphabet, multiple of four, trailing
==. Decoding that layer gives Hello%2C%20World%21. One more pass on
the percent-encoding finally yields Hello, World!. Three layers, each
individually obvious, and completely opaque if you stop after the first.
Knowing when it is not encoded at all
Three things get mistaken for encodings, and none of them decodes. A hash digest is one-way, so there is nothing to recover; digests also have fixed lengths, which is why a 64-character hex string is more likely to be SHA-256 output than a message. Encrypted data needs a key, and without it the bytes are noise whichever decoder you try. Compressed or binary payloads decode structurally while producing output no person can read, so a successful decode is not by itself proof you found the answer. For example, an attempt to decode unknown string data that turns out to be a PNG will produce bytes, and none of them will be words.
ROT13 is the honest limit in the other direction. It maps letters to letters, so its output has the same alphabet, length and shape as ordinary prose. No structural test separates it from text in a language you do not read, and for that reason this tool never claims to have found it. A detector that says nothing is more useful than one that guesses.
Related Tools
You May Also Need
You may also need
- Base64 Encoder & DecoderDecode once the alphabet is known
- URL Encoder & DecoderPeel a percent-encoded wrapper
- Hex Encoder & DecoderDecode a hex payload
Next steps
- Base64 Encoder & DecoderDecode in bulk once the encoding is identified
- JSON FormatterRead a decoded payload that turns out to be JSON
Alternatives
- Base64 Encoder & DecoderGo straight there when the encoding is already known