A zero-width decoder looks for invisible Unicode characters such as the zero-width space (U+200B) and the zero-width non-joiner (U+200C), reads them as bits, and converts the bits back into the hidden text.
Example
The input below looks like an ordinary sentence, but 16 invisible characters sit between "to" and "see". Copy it from this page to try it.
Nothing toββββββββββββββββ see herehiThe decoder reports Hidden bits: 16, which is two characters of 8 bits each.
How zero-width steganography works
Unicode has several characters that take up no space on screen:
| Code point | Name | Normal purpose |
|---|---|---|
| U+200B | Zero-width space (ZWSP) | Marks a line-break opportunity |
| U+200C | Zero-width non-joiner (ZWNJ) | Stops two letters from joining (Persian, Arabic) |
| U+200D | Zero-width joiner (ZWJ) | Joins characters, for example in emoji sequences |
| U+FEFF | Zero-width no-break space / BOM | Byte order mark at the start of a file |
Text survives copy and paste with these characters intact, so they can carry a hidden payload. A common scheme writes each bit of the secret as one of two zero-width characters. This decoder reads U+200B as 0 and U+200C as 1, groups the bits into 8-bit bytes, and turns them into text. Other characters, including U+200D, are skipped.
The same trick is used to watermark text: a leaked document or chat message can carry an invisible code that identifies the person it was sent to.
How to use the zero-width decoder
- Paste the suspicious text exactly as you received it.
- Read the hidden message and the number of hidden bits.
- If it says zero-width characters were found but no message was decoded, the text uses a different scheme. Use the Hexdump viewer to see which characters are there (
e2 80 8bis U+200B,e2 80 8cis U+200C,e2 80 8dis U+200D).
Find zero-width characters in code
import re
text = "Nothing toββ see here"
print([f"U+{ord(c):04X}" for c in re.findall("[β-βο»Ώ]", text)]) # ['U+200B', 'U+200C']
print(re.sub("[β-βο»Ώ]", "", text)) # strip themAt a glance
| Characters read | U+200B = 0, U+200C = 1 |
| Grouping | 8 bits per character |
| Common uses | Steganography, text watermarking, CTF puzzles |
| Removal | Delete U+200BβU+200D and U+FEFF |
Frequently asked questions
How can I tell if text has hidden characters?
Use the arrow keys: the cursor seems to stop between letters for no reason. Or compare the length: a string with hidden characters is longer than it looks. The Hexdump viewer shows them as e2 80 8b-style byte sequences.
Why are zero-width characters dangerous?
They can make two strings that look identical compare as different, which breaks searches, logins and code. They're also used to sneak words past content filters and to fingerprint leaked text.
Is a zero-width joiner in emoji a hidden message?
No. Emoji sequences such as π¨βπ©βπ§ use U+200D to join several emoji into one. This decoder ignores U+200D for that reason.
Last reviewed Β· found a mistake? contact@decoder.tools Β· view as markdown