⚡ Curated dev resources & dealsSponsored
DevToolBayFree Developer Tools

UTF-8 是怎么工作的:多字节与自同步

变长编码、码点与代码单元、自同步性质,以及乱码问题的排查路径。

发布于·约 2 分钟阅读

Every developer eventually hits the wall: a string that counts differently in the database, in JavaScript and in the API payload. The culprit is almost always the gap between characters, code points and bytes.

The three layers: characters, code points, bytes

A character is what a human reads. A code point is its number in the Unicode table (U+4F60 for the word ni in Chinese). A byte is what storage actually holds after UTF-8 encoding. UTF-8 uses 1 byte for ASCII, 2 bytes for most Latin accents, 3 bytes for CJK and 4 bytes for emoji.

That is why one Chinese character counts as a single character and 3 bytes — and why an emoji counts as one character, 4 bytes and two UTF-16 units in engines using surrogate pairs.

Where the counts disagree

  • Databases: VARCHAR(10) may mean 10 bytes or 10 characters depending on charset and engine.
  • JavaScript: .length counts UTF-16 units, so an emoji is 2.
  • Limits and billing: APIs that cap by bytes silently truncate multibyte text mid-character.

The Word Counter shows characters, code points and byte columns side by side, so you can see which limit actually applies to your text.

Debugging invisible characters

Copy-pasted text often drags zero-width joiners (U+200D), BOM marks (U+FEFF) or soft hyphens (U+00AD) that match nothing in your source code and break string comparisons silently. Paste the string into the Unicode Converter and every code point appears with its name — invisible ones light up instantly.

The rule of thumb

When a limit or a length matters, always ask which unit it uses: characters, code points, UTF-16 units or bytes. The Unicode inspector answers that question for any single character in seconds, fully offline.

相关指南

文中提到的工具