client-side toolkit

DASH

// deck of many prompts, static edition

A grab-bag of text encoders and ciphers, rebuilt to run 100% in your browser. Nothing is sent anywhere — every transform below is pure client-side JavaScript. Paste on the left, pick a transform, read the result on the right.

transform

~tokens is an instant rough estimate (≈ characters ÷ 4). For the real split, run a per-model tokenizer below.

tokenize

tokenizing output

Runs client-side via transformers.js. The first run for a model downloads its vocabulary (a few MB, from the jsDelivr and Hugging Face CDNs) and is then cached by the browser.

field notes — encoding layers & tokens

The interesting part of stacking these transforms isn't the bytes — it's what happens to the tokens a language model actually sees. Models don't read characters, they read tokens, and how your text splits into tokens changes completely the moment you encode it.

Natural text is cheap. A byte-pair tokenizer carries learned merges: "Hello, world!" is only ~4 tokens because those character runs co-occur constantly in training. Encoding destroys those merges — base64("Hello, world!") = SGVsbG8sIHdvcmxkIQ== becomes roughly 8–11 tokens, none of them meaningful, because the base64 alphabet doesn't line up with anything the tokenizer learned. Hex is worse; binary and morse are the least token-dense representations there are.

So every encoding layer does two things at once: it inflates the token count and it scrambles semantic locality — the local structure a model leans on to recover meaning. Stack two or three layers (base64 → rot13 → emoji) and the token stream drifts ever further from anything the model was trained to read.

Emoji is the extreme case. A plain emoji is often a single token, but a composed one — a family built from a zero-width-joined man + woman + girl + boy — can be 6–10 tokens, because it is literally that many code points glued together. That makes the emoji codec here the flashiest and the most token-expensive transform on the page: it maps every single byte to one emoji, so the token count balloons.

Why care? Encoded, layered text is a standard way to probe how a model represents input and how robustly it decodes it. There's a narrow band where a model can still round-trip an encoding that a naive plaintext filter can't read — and exactly where that band sits differs by tokenizer (cl100k, o200k, Claude's, Llama's all fragment differently). That's why the tokenizer above reports a real per-model count rather than the rough chars ÷ 4 estimate — encode something, tokenize it, then switch models and watch the same string land on different numbers.

notes

Reversibility. Most transforms round-trip exactly (base64, hex, binary, ascii, url, morse, nato, leet, braille, emoji, spaces, rot13, reverse). A few are lossy by nature and are encode-only here: disemvowel (drops vowels), pig latin (not reversible), and case (UPPER/lower). zalgo decode simply strips the combining marks back off.

Network use. Every transform on this page is pure client-side JavaScript and never touches the network. The tokenize panel is the one exception, and only when you press the button: it fetches transformers.js and the chosen model's vocabulary from a CDN, then runs the tokenizer locally. Your text still never leaves the browser. If those downloads are blocked, the panel says so and everything else keeps working.

Scoped out. The original Deck of Many Prompts also offered a network translate feature and a server-side text-to-image render. Those genuinely need a backend, so they are deliberately omitted — DASH ships as a static page.

Transform set adapted from peluche/deck-of-many-prompts. Reimplemented client-side for VoynichLabs.