Introduction
Every emoji you send might be hiding a secret. Unicode assigns many emoji characters optional variation selectors β invisible code points (U+FE0F and U+FE0E) that switch between emoji and text presentation. A message like "β€οΈππ" can carry a hidden binary payload inside those selectors while looking completely identical to the reader. This tool exploits that mechanic to embed arbitrary text into emoji strings without altering how they appear in any modern chat app or browser. Paste your carrier emoji text and your secret message below to encode it in the browser β nothing leaves your device.
What this tool does
- Hides UTF-8 text inside emoji strings by appending Unicode variation selectors (U+FE0F / U+FE0E) after each carrier emoji.
- Encodes each ASCII character as 8 successive variation-selector bits appended to consecutive emojis in the carrier.
- Decodes variation-selector sequences back to the original text from any emoji string produced by this tool.
- Processes everything client-side β no network requests are made at any point.
- Supports any emoji from the supported carrier set and produces output that renders visually unchanged in SMS, Slack, Discord, and social platforms.
How this tool works
The encoder scans the carrier string character by character. When it encounters an emoji from the supported carrier set (hearts, stars, vehicles, etc.), it reads the next character from your secret message, converts its ASCII code to an 8-bit binary string, and appends either U+FE0F (bit 1) or U+FE0E (bit 0) after the emoji for each bit in sequence. Because variation selectors are rendering hints rather than independent characters, most platforms render the output identically to the original carrier text.
The decoder performs the reverse: it iterates the input looking for U+FE0F and U+FE0E code points, accumulates them in groups of 8, converts each group to a character code, and reconstructs the hidden message. The tool shows a character count and optionally highlights where variation selectors are attached, giving you a visual inspection mode to verify encoding.
How the cipher or encoding works
Unicode variation sequences are documented in the Unicode Standard Annex #11 and expanded in Unicode Technical Standard #51 (Unicode Emoji). The variation selector block (U+FE00βU+FE0F) was originally introduced to disambiguate CJK ideographic presentation forms, but VS-15 (U+FE0E) and VS-16 (U+FE0F) were repurposed by Emoji 1.0 in 2015 to control whether a code point renders as text or emoji.
Because most text renderers treat variation selectors as combining characters that attach to the preceding base character, they do not appear as separate glyphs, are not counted in visual character counts by messaging apps, and survive most copy-paste operations intact. This makes them an effective steganographic carrier β unlike whitespace or zero-width spaces, variation selectors are semantically meaningful in Unicode so their presence alone does not prove intent to hide data.
The technique was described in academic literature as early as 2020 in research covering Unicode-based covert channels. The encoding capacity is constrained by the number of carrier emojis in the string: hiding one ASCII character requires 8 emojis. A 140-character tweet with 20 emojis can carry just 2 hidden ASCII characters, so this method suits short secrets (keys, identifiers, watermarks) rather than long messages.
How to use this tool
- Type or paste your carrier text in the 'Visible Text' field. It must contain at least one supported emoji per character you want to hide.
- Type your secret message in the 'Hidden Message' field.
- Click 'Encode' β the output looks identical to your carrier text but now contains embedded variation selectors.
- Share the encoded output through any channel that preserves Unicode (most chat apps, email, web).
- To decode, paste the encoded string into the 'Decode' tab and click 'Decode'. The hidden message is extracted from the variation selectors.
Real-world examples
Watermarking a social media post
A content creator publishes short emoji-heavy captions on Instagram. To track scrapers and plagiarists, they encode a 4-character identifier ("usr1") inside the 32 emojis in their standard signature line. If that caption later reappears elsewhere, they paste it into the decoder and instantly confirm the identifier β proving the text originated from their account without any visible mark.
CTF challenge embedding
A security competition organiser embeds a 6-character flag ("CTF{X}") inside an emoji string posted to the competition Discord. The post reads "Great puzzle! πβππ«π₯β¨β€οΈπππππ€πΈπΊπ»π·πΉπππππππβ‘ππππβοΈπ" β perfectly normal to participants until they think to run it through a steganography decoder. The flag only resolves correctly when all 32 emojis are present in the right order.
Debugging emoji variation-selector stripping
A developer builds a messaging API and needs to verify it preserves variation selectors end-to-end. They encode the string "ALIVE" (5 ASCII chars, needing 40 emojis) into a test string, POST it through their API, and then run the decoded output through this tool. If the decoder returns "ALIVE", the pipeline is variation-selector-safe. If it returns garbage or nothing, the API is stripping non-standard Unicode code points.
Comparison with similar methods
| Method | Complexity | Typical use |
|---|---|---|
| Emoji variation selectors | Low (1 bit/emoji) | Short watermarks, CTF challenges, covert identifiers |
| Zero-width characters | LowβMedium | Hiding data in prose text without emojis |
| Whitespace steganography | Low | Document watermarking, survives less copy-paste |
| CSS/HTML attribute steganography | Medium | Web page content watermarking |
Limitations or considerations
Capacity is low: each ASCII character requires 8 carrier emojis. Some platforms normalise emoji variation selectors on render or on paste β notably Twitter trims VS-16 from some code points. The technique only supports emoji present in the hard-coded carrier set; random text with no emojis cannot act as a carrier. This method provides obscurity, not secrecy. Anyone running the string through a Unicode inspector (e.g., `python -c "for c in s: print(hex(ord(c)))"`) will see the variation selectors. Combine with AES encryption of the payload before encoding for confidentiality.
Frequently asked questions
Conclusion
Emoji steganography turns something as ordinary as a heart or star into a carrier for hidden data. The technique is narrow in scope β low capacity, constrained to emoji-carrying strings β but for watermarking short identifiers or building CTF challenges, it is clean and effective. Pair the output with explicit encryption if the payload needs to remain confidential, not just hidden. Check out the Zero-Width Steganography tool if you need to hide data in ordinary prose without emojis.