Character Encoding Reference

A character encoding maps text to bytes. This table covers common encodings like ASCII, UTF-8, GBK, GB2312, Big5, ISO-8859-1 with meaning and typical use, helping with mojibake and encoding choices.

How It Works

A charset is a mapping from characters to numeric code points. Early systems defined their own (GBK, Big5, Shift-JIS), which were incompatible; Unicode unifies every language into one code space (code points from U+0000), fixing mojibake at the root.

UTF-8 is a variable-length Unicode encoding: ASCII stays 1 byte, other characters take 2–4 bytes. It is ASCII-compatible and self-synchronizing, which is why it is the default for the web and Linux. Garbled text almost always means the writer's encoding differs from the reader's assumed encoding.

When to Use This Table

This table is for making encoding declarations explicit. It lists the byte structure and typical use of common encodings such as ASCII, UTF-8, UTF-16, GBK, Big5, Shift_JIS and ISO-8859-1. The first step in any mojibake investigation is confirming both ends agree.

When not to consult it: you are designing a transcoding strategy or doing automatic encoding detection. GBK and UTF-8 do not map one to one, and GBK contains many characters incompatible with Unicode, so guessed encodings can look plausible yet be wrong; that needs a dedicated detection library.

Rule of thumb: use UTF-8 everywhere, and declare it explicitly, with a BOM or an explicit marker. Most historical Shift_JIS and GBK incidents trace back to one side not declaring its encoding, or declaring something that does not match reality, rather than to the encoding being poor.

Mind that UTF-8 with and without a BOM are not interchangeable: the BOM is read as the first character of the payload, which makes JSON parsing fail, puts invisible junk at the head of a file, and makes string comparisons unequal. It is the classic case of data that looks fine yet is subtly wrong.

Boundaries and Common Pitfalls

  • A UTF-8 BOM makes JSON parsing fail outright

    JSON with a BOM throws Unexpected token in JSON.parse, because U+FEFF is not a legal leading character in the JSON grammar. Writers add it frequently — CSVs exported from Excel in particular — while readers do not strip it. Defences: skip the first three bytes when they are EF BB BF; never add a BOM to JSON or API responses. CSV is the exception: spreadsheet software relies on the BOM to detect encoding, so keep it there.

  • Mojibake from mismatched encodings propagates in both directions

    The classic double mojibake reads UTF-8 as Latin-1 and writes it back as UTF-8, turning Chinese into æ¼ ä¸­æ–‡ — and once persisted that result is no longer automatically recoverable, since the information was lost at the first conversion. Subtler cases stay reversibly round-trippable, yet the moment they were written to a database the field lengths, indexes and regex matching may already be wrong. The discipline is to allow UTF-8 end to end and convert only at explicit boundaries.

  • When the extension disagrees with the real encoding, guessing by name fails

    A .csv file may be UTF-8, GBK, Shift_JIS or UTF-8 with BOM — the extension carries no encoding information at all, so code like if (ext === ’.csv’) useUtf8 is simply wrong. The reliable order is: check for a BOM (EF BB BF means UTF-8, FF FE means UTF-16LE); validate the first bytes against candidate encodings; ask the user or probe on upload; and only then fall back to heuristics, and then with a confidence score attached.

How This Relates to Neighbours

To see what a character looks like and its code point, use the in-site ASCII page; this one covers encoding scheme choice and declaration.

The relationship between percent-encoding and character encoding (why a Chinese character becomes three %XX) belongs to the URL encoding page, a different layer.

How HTML entities and percent-encoding stack belongs to the HTML entities page, which this one does not cover.

If the goal is debugging concrete mojibake you need the raw bytes: detection relies on comparing file header, declared encoding and actual rendering, which this table alone cannot provide.

Practical Snippet

Key points: (1) strip the BOM on read, never add one to JSON or API responses, and do add it to CSV so Excel recognises UTF-8; (2) extensions carry no encoding information, so never branch on if (ext === ’.csv’); (3) detect in the order BOM → byte-level validation → user-specified → heuristics with a confidence score; (4) once double mojibake is persisted the information is gone and only the original data can restore it, so block it at the entry point; (5) allow UTF-8 end to end and convert only at explicit boundaries.

// ① 检测 BOM(读文件前必做)
function stripBom(buf) {
  const b = new Uint8Array(buf)
  if (b.length >= 3 && b[0] === 0xef && b[1] === 0xbb && b[2] === 0xbf) return b.slice(3)
  return b
}

// ② 按 BOM 判断 UTF-16 / UTF-8
function sniffEncoding(buf) {
  const b = new Uint8Array(buf)
  if (b.length >= 2 && b[0] === 0xff && b[1] === 0xfe) return 'utf-16le'
  if (b.length >= 2 && b[0] === 0xfe && b[1] === 0xff) return 'utf-16be'
  if (b.length >= 3 && b[0] === 0xef && b[1] === 0xbb && b[2] === 0xbf) return 'utf-8-bom'
  return 'unknown'   // 未命中就走内容探测或让用户选
}

// ③ 🔴 带 BOM 的 JSON 会让 JSON.parse 直接抛错
const badJson = new TextDecoder('utf-8').decode(
  new Uint8Array([0xef, 0xbb, 0xbf, ...new TextEncoder().encode('{"a":1}')]))
try { JSON.parse(badJson) } catch (e) { console.log('抛错:', e.message) }   // Unexpected token

// ④ 读取 CSV:先剥 BOM,再按声明/探测的编码解码
import { parse } from 'papaparse'
function readCsv(buf, encoding = 'utf-8') {
  const text = new TextDecoder(encoding).decode(stripBom(buf))
  return parse(text, { header: true, skipEmptyLines: true })
}

// ⑤ 写入侧:JSON 绝不加 BOM;CSV 加 BOM(让 Excel 正确识别 UTF-8)
const jsonStr = JSON.stringify({ a: 1 })
const csvStr = '' + 'name
age
'          // BOM 前置
console.log(jsonStr.charCodeAt(0) === 0xfeff)        // false ✅

// ⑥ 检测是否发生双重乱码(出现典型乱码字符)
const mojibake = /[ÃÂæ¼][€-￿]/
console.log(mojibake.test('æ¼ ä¸­æ–‡'))             // true ⇒ 需从原始数据恢复

Practical Notes

  • A UTF-8 BOM breaks JSON parsingFiles saved as "UTF-8 with BOM" by Windows Notepad start with EF BB BF, and JSON.parse throws Unexpected token; in PHP the symptom is "headers already sent". Save data files as UTF-8 without BOM, or strip the first three bytes before parsing.
  • MySQL utf8 is really utf8mb3 and cannot store emojiHistorically MySQL utf8 covered at most 3 bytes, so 4-byte characters (emoji, rare CJK) were truncated or raised Incorrect string value. Use utf8mb4 for new databases and make sure character_set_client on the connection is utf8mb4 too.
  • Encoding and charset are two layers; conflating them hides the root causeUTF-8 is an encoding (how bytes are arranged) while Unicode is a character set (how code points are assigned). Mojibake is almost always "written with encoding A, read as B". Always verify both declarations first before touching code.

Data Sources

  • IANA Character Sets Registry
  • The Unicode Standard
  • ISO/IEC 8859 series
  • GB 18030-2022
  • RFC 3629 (UTF-8)

Codes, names and definitions above come from public specifications; we claim no originality over the specification data itself. The arrangement, Chinese annotations and practical notes on this page are written by us.

EncodingMeaningTypical Use
ASCII7-bit charset covering English letters, digits and basic symbols (0-127)Oldest base encoding, compatible subset of all modern encodings
UTF-8Variable-length Unicode encoding, 1-4 bytesWeb default; covers every language; Chinese is 3 bytes
UTF-16Unicode 2 or 4 byte encodingCommon in Windows/Java/.NET internals; JS string backing
UTF-32Fixed 4-byte Unicode encodingSimple but bulky; rarely used for transfer
ISO-8859-1Latin-1, single-byte for Western European languagesHTTP default; often confused with Windows-1252
Windows-1252CP1252, superset of Latin-1 with € and more printable charsWindows Western default; browsers often parse 8859-1 as 1252
GBKChinese internal code extension, double-byte for simplified+traditionalOld Chinese Windows default; compatible with GB2312
GB2312Early simplified-Chinese double-byte encodingBasic simplified charset, fully covered by GBK
GB18030Mandatory national standard covering CJK and minority scriptsRequired by Chinese gov/finance; compatible with GBK
Big5Big-5, traditional-Chinese double-byte encodingTraditional Chinese encoding in HK/Taiwan
Shift-JISJapanese encoding, mixed single/double byteJapanese Windows default
EUC-KRKorean double-byte encodingTraditional Korean encoding

Frequently Asked Questions

What is the difference between UTF-8 and GBK?

UTF-8 is a variable-length Unicode encoding covering every language — the de-facto web standard. GBK is a Chinese double-byte encoding covering only Chinese and English; it is smaller but cannot represent other languages. Modern projects should standardize on UTF-8 to avoid mojibake.

Why does mojibake (garbled text) happen?

Mojibake appears when text saved in encoding A is decoded as encoding B. The most common case is Chinese saved as GBK but read as UTF-8 (or vice versa). Keep file, database and HTTP charset (charset=utf-8) consistent to avoid it.

Are ISO-8859-1 and Windows-1252 the same?

No, but they are often confused. 8859-1 has control characters in 0x80-0x9F; 1252 puts printable characters there (e.g. €, smart quotes). Browsers often parse a declared 8859-1 as 1252, so 1252 is the clearer choice.

Which encoding do emoji use?

Emoji are Unicode; under UTF-8 they are usually 4 bytes (more for some new ones), and under UTF-16 a surrogate pair. As long as the system uses UTF-8, emoji store and display correctly.