首页/开发/正则与编码速查/GBK 编码结构与双字节规则

GBK 编码结构与双字节规则

GBK 是 GB2312 的双字节扩展:0x00-0x7F 保留 ASCII,汉字用首字节 0x81-0xFE 加第二字节 0x40-0xFE 表示,共收录两万余汉字;Windows 的 cp936 与它基本等价,遇上 UTF-8 混用就产生乱码。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌​‌‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌‌​​‌​​‌‌‌​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌‌​‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

GBK 的编码结构

GBK 在 GB2312 基础上扩充而来,采用变长结构:单字节区 0x00-0x7F 与 ASCII 完全一致,汉字与符号用双字节表示,首字节范围 0x81-0xFE,第二字节范围 0x40-0xFE 且不含 0x7F。它把 GB2312 的 6763 个汉字扩到两万余个,收录了繁体字、生僻字与更多符号,因此在中文字符集里长期扮演「能用就行」的角色。Windows 上标注为 ANSI 的默认中文编码(代码页 936)即由此实现。

基本信息

常见标识GBK、CP936、MS936;Java 里的 GB2312 有时实际按 GBK 处理
字节结构单字节 ASCII + 双字节汉字,最长 2 字节
双字节首字节0x81-0xFE
双字节第二字节0x40-0x7E 与 0x80-0xFE(避开 0x7F)
汉字规模GBK 收录 CJK 统一汉字 20902 个(含 GB2312 全部)
与 ASCII 关系单字节区完全兼容,英文内容不受影响

典型使用场景

  • Windows 中文环境默认读写:记事本以 ANSI 保存、老程序写出的配置文件通常是 CP936
  • 旧 Java 工程:file.encoding=GBK 或系统默认编码下的源码、日志文件
  • 面向 Excel 的 CSV 导出:不写 BOM 时用 GBK 可被简体中文 Office 直接识别
  • 与 legacy 系统对接:老 ERP、票据打印、串口设备出中文时使用 GBK
  • 数据迁移前的摸底:统计历史库里哪些表用了 gbk 字符集

判定与转换示例

判定与转换示例
file -i legacy.txt                  # 输出 charset=iso-8859-1 或 unknown 时,多半是 GBK 系
iconv -f GBK -t UTF-8 legacy.txt -o utf8.txt   # 转码;先在小文件上验证
iconv -f GBK -t UTF-8 legacy.txt > /dev/null   # 只校验:报 illegal input sequence 说明不是 GBK
python -c "print(open('legacy.txt','rb').read(4))"   # 看前几字节是否落在 0x81-0xFE,粗判双字节编码
# Python 侧显式指定编码,避免依赖系统默认值
python -c "print(open('legacy.txt', encoding='gbk').readline())"

字节区间对照

字节位置取值区间含义
单字节0x00-0x7FASCII 字符,与英文编码一致
双字节首字节0x81-0xFE进入双字节状态;0xFF 不是合法取值
双字节第二字节0x40-0x7E / 0x80-0xFE跳过 0x7F,使 DEL 不会出现在字符中间
GB2312 兼容区首字节 0xB0-0xF7常用一级、二级汉字所在区间
符号与全角区首字节 0xA1-0xA9标点、全角字母数字等
解析 GBK 时不能逐字节判定:必须「读首字节 → 判断是否大于 0x7F → 决定后面还有几字节」的状态机。漏掉这一步会把汉字的首字节当成独立字符,产生错位与后续整段乱码。
同一份内容混用 GBK 与 UTF-8 是乱码的主因:GBK 汉字字节在 UTF-8 解码器里属于非法序列(报错或被替换成问号),UTF-8 三字节汉字按 GBK 解则变成两三个不知所云的汉字。定位时先看字节,再谈编码。
跨平台项目应统一到 UTF-8:GBK 无法表示 emoji 与增补平面汉字,且不同系统对 CP936 的实现细节存在历史差异。确需向下兼容时,用 GB18030 作为超集,它是 GBK 的严格扩展,可覆盖 Unicode 全部码位。

易错点

  • 把 GBK 文件当 UTF-8 读:整个中文段落变成问号或替换字符,且原始字节在写回时被破坏 → 读之前确认编码,写回时使用同一编码
  • 按字节切片处理中文:切断汉字两字节序列,尾部出现半个字符 → 按字符或按行切分,或用支持编码的库
  • 在 UTF-8 数据库里存 GBK 字节流:查询与排序全乱,索引失效 → 入库前转码,或先改库表字符集
  • 以为 GBK 能覆盖所有汉字:生僻字、增补平面字符编码失败抛异常 → 需要全量覆盖时用 GB18030 或 UTF-8
  • 依赖系统默认编码做程序内编解码:开发机 GBK、服务器 UTF-8 导致上线才复现 → 所有读写接口显式指定编码

数据来源与参考

  • GB2312 / GBK 相关国家标准(GB 2312-1980、GBK 技术规范)
  • Microsoft 文档:代码页标识符(936, GBK/Chinese Simplified)
  • WHATWG Encoding Standard:GBK 编码与标签映射

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/gbk-encoding-structure.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​​‌‌‌​‌‌​​​‌​​‌‌​‌​‌‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌‌​​‌​​‌‌‌​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌‌​‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​