← Diggwigs field notes

One greeting, three different ideas of length

Consider a message containing only a waving hand: 👋. It looks like one character, uses two UTF-16 code units in JavaScript, and needs four UTF-8 bytes. A length mismatch can come from measuring different representations of the same text.

Inspect the bytes with a local example

In Base64 Lab, choose UTF-8 text and Encode. Paste the emoji without surrounding quotes or spaces.

Input: 👋
Expected Base64: 8J+Riw==
Expected source bytes: 4

Switch to Decode with that Base64 value. The expected text is the same waving hand. Switch to Binary file mode while decoding to inspect the actual bytes:

f0 9f 91 8b

Choose the measurement your boundary needs

A byte limit belongs to an encoding. A database column limit, a network content length, and a user-facing character counter need not use the same unit. JavaScript’s string length counts UTF-16 code units; it does not directly measure UTF-8 storage or visible symbols.

This standalone JavaScript example can run in a developer console. It inspects fixed data and requires no libraries.

const greeting = "👋";
greeting.length;                         // 2 UTF-16 code units
[...greeting].length;                    // 1 Unicode code point
new TextEncoder().encode(greeting).length; // 4 UTF-8 bytes

Do not normalize without a contract

The letter é can be represented as one code point or as e followed by a combining accent. They can appear identical while producing different bytes and different Base64. Diggwigs does not silently normalize your text.

Input: é
Expected Base64: w6k=

Input: é (e + U+0301 combining acute accent)
Expected Base64: ZcyB

More complex emoji can contain several code points joined into one visible symbol. When designing a character counter, use grapheme segmentation appropriate to the product. When checking a wire format, inspect the encoded bytes.

Preserve the original text while investigating. A cleanup step can erase the exact difference you were trying to find.

Diggwigs field notes pair a concrete input with its expected output. Run the examples in the local workspace and inspect the boundary for yourself.