Introduction
GB18030 is China’s national standard for text. It contains GB 2312 and GBK, and it covers every Unicode code point, so it is in effect a Unicode encoding. A character takes one, two or four bytes. Its editions are GB 18030-2000 (17 March 2000), GB 18030-2005 (8 November 2005, whose mandatory part has been required of software sold in China since 1 May 2006) and GB 18030-2022 (in force from 1 August 2023). The WHATWG Encoding Standard defines it for browsers, with the 2022 mapping.
A file with only one- and two-byte characters cannot be told from GBK, and is read there. A file with the byte order mark below, or with four-byte sequences, is read here.
A file dropped on any page of this site opens in the explorer, which shows its structure and decodes its characters.
Structure
0Byte order mark84 31 95 33, when present0 or 4 bytes0 or 4Lines characters of one, two or four bytesvaries…End-of-file mark and zero padding, as in other byte-oriented textrare
Byte order mark
U+FEFF is four bytes in GB18030: 84 31 95 33. It is optional and
uncommon, and like UTF-8’s mark it only says what the text is, not its byte order,
because the bytes come one at a time. The explorer treats those first four bytes as
the mark. A U+FEFF further on is an ordinary character.
Encoding
| Bytes | Form | Holds |
|---|---|---|
| 1 | 00–7F; 80 in browsers is € | ASCII |
| 2 | lead 81–FE, trail 40–7E or 80–FE | GB 2312 and GBK: mostly CJK ideographs, plus symbols |
| 4 | 81–FE, 30–39, 81–FE, 30–39 | every other Unicode code point |
The second byte tells a two-byte character from a four-byte one:
30–39 starts a four-byte form, and every other valid value
a two-byte form. So every byte above 7F starts a character, or continues
one, by the rules above; a FF starts nothing.
Two-byte characters
The two-byte forms map to Unicode through the 23,940-entry table the WHATWG
standard calls index-gb18030. Together with the four-byte ranges below
this covers all of Unicode. The table is too long to give here; the
standard’s index
has every entry, and the explorer uses the browser’s decoder, which holds it.
Four-byte characters
Write the four bytes as b1 b2 b3 b4. The pointer is:
pointer = (b1 − 0x81) × 12600 + (b2 − 0x30) × 1260 + (b3 − 0x81) × 10 + (b4 − 0x30)
A pointer from 0 to 39419 is in the Basic Multilingual Plane; one from 189000 to 1237575 is above it; any other is not a character.
- Above U+FFFF: code point =
0x10000+ pointer −189000. So90 30 81 30is U+10000 andE3 32 9A 35is U+10FFFF. - In the Basic Multilingual Plane: find in the table below the last row whose pointer is not greater than this pointer. The code point is that row’s code point plus the difference of the pointers. So pointer 0 is U+0080, and pointer 37 is U+00A6.
The 207 ranges of the WHATWG index-gb18030-ranges table
| Pointer | Code point | Pointer | Code point |
|---|---|---|---|
| 0 | U+0080 | 36 | U+00A5 |
| 38 | U+00A9 | 45 | U+00B2 |
| 50 | U+00B8 | 81 | U+00D8 |
| 89 | U+00E2 | 95 | U+00EB |
| 96 | U+00EE | 100 | U+00F4 |
| 103 | U+00F8 | 104 | U+00FB |
| 105 | U+00FD | 109 | U+0102 |
| 126 | U+0114 | 133 | U+011C |
| 148 | U+012C | 172 | U+0145 |
| 175 | U+0149 | 179 | U+014E |
| 208 | U+016C | 306 | U+01CF |
| 307 | U+01D1 | 308 | U+01D3 |
| 309 | U+01D5 | 310 | U+01D7 |
| 311 | U+01D9 | 312 | U+01DB |
| 313 | U+01DD | 341 | U+01FA |
| 428 | U+0252 | 443 | U+0262 |
| 544 | U+02C8 | 545 | U+02CC |
| 558 | U+02DA | 741 | U+03A2 |
| 742 | U+03AA | 749 | U+03C2 |
| 750 | U+03CA | 805 | U+0402 |
| 819 | U+0450 | 820 | U+0452 |
| 7922 | U+2011 | 7924 | U+2017 |
| 7925 | U+201A | 7927 | U+201E |
| 7934 | U+2027 | 7943 | U+2031 |
| 7944 | U+2034 | 7945 | U+2036 |
| 7950 | U+203C | 8062 | U+20AD |
| 8148 | U+2104 | 8149 | U+2106 |
| 8152 | U+210A | 8164 | U+2117 |
| 8174 | U+2122 | 8236 | U+216C |
| 8240 | U+217A | 8262 | U+2194 |
| 8264 | U+219A | 8374 | U+2209 |
| 8380 | U+2210 | 8381 | U+2212 |
| 8384 | U+2216 | 8388 | U+221B |
| 8390 | U+2221 | 8392 | U+2224 |
| 8393 | U+2226 | 8394 | U+222C |
| 8396 | U+222F | 8401 | U+2238 |
| 8406 | U+223E | 8416 | U+2249 |
| 8419 | U+224D | 8424 | U+2253 |
| 8437 | U+2262 | 8439 | U+2268 |
| 8445 | U+2270 | 8482 | U+2296 |
| 8485 | U+229A | 8496 | U+22A6 |
| 8521 | U+22C0 | 8603 | U+2313 |
| 8936 | U+246A | 8946 | U+249C |
| 9046 | U+254C | 9050 | U+2574 |
| 9063 | U+2590 | 9066 | U+2596 |
| 9076 | U+25A2 | 9092 | U+25B4 |
| 9100 | U+25BE | 9108 | U+25C8 |
| 9111 | U+25CC | 9113 | U+25D0 |
| 9131 | U+25E6 | 9162 | U+2607 |
| 9164 | U+260A | 9218 | U+2641 |
| 9219 | U+2643 | 11329 | U+2E82 |
| 11331 | U+2E85 | 11334 | U+2E89 |
| 11336 | U+2E8D | 11346 | U+2E98 |
| 11361 | U+2EA8 | 11363 | U+2EAB |
| 11366 | U+2EAF | 11370 | U+2EB4 |
| 11372 | U+2EB8 | 11375 | U+2EBC |
| 11389 | U+2ECB | 11682 | U+2FFC |
| 11686 | U+3004 | 11687 | U+3018 |
| 11692 | U+301F | 11694 | U+302A |
| 11714 | U+303F | 11716 | U+3094 |
| 11723 | U+309F | 11725 | U+30F7 |
| 11730 | U+30FF | 11736 | U+312A |
| 11982 | U+322A | 11989 | U+3232 |
| 12102 | U+32A4 | 12336 | U+3390 |
| 12348 | U+339F | 12350 | U+33A2 |
| 12384 | U+33C5 | 12393 | U+33CF |
| 12395 | U+33D3 | 12397 | U+33D6 |
| 12510 | U+3448 | 12553 | U+3474 |
| 12851 | U+359F | 12962 | U+360F |
| 12973 | U+361B | 13738 | U+3919 |
| 13823 | U+396F | 13919 | U+39D1 |
| 13933 | U+39E0 | 14080 | U+3A74 |
| 14298 | U+3B4F | 14585 | U+3C6F |
| 14698 | U+3CE1 | 15583 | U+4057 |
| 15847 | U+4160 | 16318 | U+4338 |
| 16434 | U+43AD | 16438 | U+43B2 |
| 16481 | U+43DE | 16729 | U+44D7 |
| 17102 | U+464D | 17122 | U+4662 |
| 17315 | U+4724 | 17320 | U+472A |
| 17402 | U+477D | 17418 | U+478E |
| 17859 | U+4948 | 17909 | U+497B |
| 17911 | U+497E | 17915 | U+4984 |
| 17916 | U+4987 | 17936 | U+499C |
| 17939 | U+49A0 | 17961 | U+49B8 |
| 18664 | U+4C78 | 18703 | U+4CA4 |
| 18814 | U+4D1A | 18962 | U+4DAF |
| 19043 | U+9FA6 | 33469 | U+E76C |
| 33470 | U+E7C8 | 33471 | U+E7E7 |
| 33484 | U+E815 | 33485 | U+E819 |
| 33490 | U+E81F | 33497 | U+E827 |
| 33501 | U+E82D | 33505 | U+E833 |
| 33513 | U+E83C | 33520 | U+E844 |
| 33536 | U+E856 | 33550 | U+E865 |
| 37845 | U+F92D | 37921 | U+F97A |
| 37948 | U+F996 | 38029 | U+F9E8 |
| 38038 | U+F9F2 | 38064 | U+FA10 |
| 38065 | U+FA12 | 38066 | U+FA15 |
| 38069 | U+FA19 | 38075 | U+FA22 |
| 38076 | U+FA25 | 38078 | U+FA2A |
| 39108 | U+FE32 | 39109 | U+FE45 |
| 39113 | U+FE53 | 39114 | U+FE58 |
| 39115 | U+FE67 | 39116 | U+FE6C |
| 39265 | U+FF5F | 39394 | U+FFE6 |
| 189000 | U+10000 |
What changed between editions
The three editions use the same byte structure, and differ in what a few codes mean:
| Edition | Byte code | Meaning before | Meaning after |
|---|---|---|---|
| 2005 (from 2000) | A8 BC | U+E7C7 (private use) | U+1E3F (ḿ) |
| 2005 | 81 35 F4 37 | U+1E3F | U+E7C7 |
| 2022 (from 2005) | A6 D9 | U+E78D | U+FE10 |
A6 DA | U+E78E | U+FE12 | |
A6 DB | U+E78F | U+FE11 | |
A6 DC | U+E790 | U+FE13 | |
A6 DD | U+E791 | U+FE14 | |
A6 DE | U+E792 | U+FE15 | |
A6 DF | U+E793 | U+FE16 | |
A6 EC | U+E794 | U+FE17 | |
A6 ED | U+E795 | U+FE18 | |
A6 F3 | U+E796 | U+FE19 | |
| 2022 | FE 59 | U+E81E | U+9FB4 |
FE 61 | U+E826 | U+9FB5 | |
FE 66 | U+E82B | U+9FB6 | |
FE 67 | U+E82C | U+9FB7 | |
FE 6D | U+E832 | U+9FB8 | |
FE 7E | U+E843 | U+9FB9 | |
FE 90 | U+E854 | U+9FBA | |
FE A0 | U+E864 | U+9FBB |
The explorer shows these with their 2022 meanings, as browsers do, and adds a note when a file uses one of them.
Lines
A line is the characters up to a line ending. Characters are counted as characters, not bytes. Tabs, form feeds and vertical tabs are counted, as in ASCII text.
Line endings
Line endings are the ASCII bytes:
| Name | Bytes |
|---|---|
| LF | 0A |
| CR LF | 0D 0A |
| CR | 0D |
These bytes never occur inside a two-byte or four-byte character, since the trail
bytes of two-byte forms start at 40 and four-byte forms use
30 to 39 and 81 to FE.
End of the file
Ctrl-Z (1A) at the end is shown as an End-of-file mark, and NUL bytes
after the text as Zero padding, as in other byte-oriented text.
Problems
| Problem | Meaning |
|---|---|
| invalid byte sequence | a lead byte with no valid second byte, a two-byte form with no character in the table, or a four-byte form outside the ranges above |
| character cut short by the end of the file | the file ends inside a character |
| NUL character | a 00 byte in the text |
| control character | a C0 control other than tab, LF, form feed and CR, or DEL (7F) |
| mixed line endings | more than one kind of line ending |
Telling it apart
The explorer reads a file as GB18030 when it starts with 84 31 95 33, or
when, without a mark, the first 64 KB are valid GB18030 and hold at least one
four-byte sequence. Without one a file cannot be told from GBK, and it is left to the
legacy format. UTF-8 is tried first, and takes any
file whose sequences are valid UTF-8.
Variants
- UTF-8 text – one to four bytes a character, ASCII unchanged
- UTF-16LE text – two or four bytes a character, low byte first
- UTF-16BE text – two or four bytes a character, high byte first
- UTF-32LE text – four bytes a character, low byte first
- UTF-32BE text – four bytes a character, high byte first
- Legacy code page text – a pre-Unicode code page that the file does not name
- UTF-7 text – Unicode as pure ASCII, with Base64 runs
- ISO-2022 and HZ text – 7-bit Japanese, Korean and Chinese with escape sequences
- GB18030 text – China’s national encoding, one, two or four bytes a character
- EBCDIC text – IBM mainframe text, not based on ASCII
Links
Developers
- ICU – conversion between encodings, including GB18030 (C, C++, Java)
- GNU libiconv – the iconv conversion library and command (C)
- encoding_rs – GB18030 as the WHATWG standard defines it (Rust)
- TextDecoder – browsers’ built-in decoder, which reads GB18030 (JavaScript)
Reference
- WHATWG Encoding Standard – the GB18030 decoder and its tables
- index-gb18030 – the 23,940 two-byte forms
- index-gb18030-ranges – the four-byte ranges, as above