软件开发人员经常遇到“中文乱码”、“软件不能显示日文”等类似问题。真相只有一个——对字符集编码没有一个系统的认知。
常见字符集编码有gb2312、gbk、big5、utf-8、utf-16,甚至有些从事mfc开发的人可能还会说字符集有ansi和unicode。真的是这样吗?直接上干货。
字符集分类
1. ansi
american national standards institute 美国国家标准学会,由这个标准学会制订的一种编码规则。
采用多字节系统 (mbcs) 的变长编码,每个字符可以是单个字节、双字节,也可以是多字节的;
兼容单字节字符集 (sbcs) 和双字节字符集 (dbcs);
兼容 euc/euc-cn 双字节编码。由于兼容了这个编码,那么 ansi 的双字节编码也是大端存储 (big endian) 的了;
不同的国家和地区可以使用不同的编码规则,这些编码对应到这些国家和地区的代码页 (code page) 上。
1.1. ascii编码
ascii编码即美国信息交换标准代码(american standard code for information interchange)是一套共有128个字符的编码,它基于阿拉丁字母,主要作用是用来表示英语和西欧语言字符。ascii规范编码第一次公布于1967年,ascii码在1986年完成最后一次更新。ascii码对照表等同于国际标准 iso/iec 646,ascii码对照表是世界最通用的信息交换标准。
ascii编码
1.2. gb2312编码
gb2312简体中文编码,一个汉字占用2个字节,在大陆是主要的编码方式,兼容ascii编码。
为了支持繁体字,于是推出了gbk编码,gbk是国标扩展(guo biao kuozhan)编码的缩写,兼容gb2312。
为了支持少数名民族的文字,于是推出了gb1803,解决了中文、日文、朝鲜语等的编码,兼容gbk。
中文编码
2. unicode编码
unicode又称为统一码、万国码、单一码,是国际组织制定的旨在容纳全球所有字符的编码方案,包括字符集、编码方案等,它为每种语言中的每个字符设定了统一且唯一的二进制编码,以满足跨语言、跨平台的要求。
unicode字符集被划分为 17 个平面(即,17个区,编号为 0-16 ),且具有以下特点:
每个平面有216 = 65536个代码点,因此,整个unicode字符集共有17 × 65536 = 111 4112 个码点。
整个unicode字符集的码点空间为u+000000 ~ u+10ffff
每个平面的码点范围可表示为u+xx0000 ~ u+xxffff,其中xx表示16进制的0x00到0x10,比如,平面0的码点范围为u+000000 ~ u+00ffff,平面2的码点范围为u+020000 ~ u+02ffff,平面15的码点范围为u+0f0000 ~ u+0fffff
再次注意:并不是每个码点就一定对应有一个字符,因为,目前unicode字符集中有很多码点都还未被使用。
unicode 17 层平面
2.1. utf-16编码
utf-16编码源于ucs-2,是unicode最早的编码方式。
ucs-2编码仅覆盖了基本平面(即bmp,第0平面)中的码点,使用固定的两字节将字符编号(类似于unicode中的码点值)直接映射为字符编码,中间未经过任何的编码算法转换。
很明显,16位的二进制位(范围为0x0000 ~ 0xffff)无法表示unicdoe引入的增补平面中的码点(平面1 ~ 16,码点范围为0x10000~0x10ffff),为此,unicode在utf-16编码中使用“代理(代替)机制”来解决这个问题,代理机制使用4个字节来表示增补平面中的码点,从而使utf-16成为一种变长编码方式。
因此,若软件仅支持ucs-2编码,则意味着仅支持ucs字符集或unicode字符集基本平面中的字符,而不支持增补平面中的字符。
utf-16编码后的码元序列在映射为物理意义上的字节序列时,又分为utf-16be (大端序),utf-16le (小端序)两种情况,大端序和小端序又分为带有字节序标记(with bom)和不带字节序标记(without bom)两种情形。比如,“abc”这三个字符的utf-16编码(码元序列)为:00 41 00 42 00 43;其对应的各种字节序列如下表所示:
”abc”的各种utf-16编码
2.2. utf-32编码
utf-32是一种将unicode字符编码的协定,对每一个unicode码位使用恰好32位元。其它的unicode transformation formats则使用不定长度编码。因为utf-32对每个字符都使用4字节,就空间而言,是非常没有效率的。特别地,非基本多文种平面的字符在大部分文件中通常很罕见,以致于它们通常被认为不存在占用空间大小的讨论,使得utf-32通常会是其它编码的二到四倍。虽然每一个码位使用固定长定的字节看似方便,它并不如其它unicode编码使用得广泛。
与utf-16一样,也存在大端和小端存储。
2.3. utf-8编码
utf-8编码是unicode编码的一种编码形式。由1-6个字节表示一个字符,兼容ascii编码。
utf-8编码
3. mfc中的字符集
mfc字符集选择多字节编码时,对应的编码是gbk编码
mfc字符集选择unicode编码时,对应的编码是utf-16编码。
4. qt中的字符集
qstring是按utf-16存储的。
1、当选择utf-8编码时,qstring构造函数的参数对应utf-8编码(默认设置)。
qtextcodec *codec = qtextcodec::codecforname(utf-8); qtextcodec::setcodecforlocale(codec); qstring str = “右边是uft-8编码的字符串”;
2、当选择gbk编码时,qstring构造函数的参数对应gbk编码。
qtextcodec *codec = qtextcodec::codecforname(utf-8); qtextcodec::setcodecforlocale(codec); qstring str = “右边是gbk编码的字符串”;
3、qstring也可以指定编码赋值。
qstring str1 = qstring::fromlocal8bit(“gbk编码字符串”); qstring str2 = qstring::fromutf8(“utf-8编码字符串”);
华山论剑:AI大模型时代的高性能网络如何演进?
RFID在日本服装业中有着怎样的应用
关于电动汽车,多少续航里程比较合适
计算机视觉多领域应用,加速物联网时代步伐!
芯圣电子推出资源型8位触摸单片机HC88T36X1系列
一文带你搞懂字符集编码
智能家居需求崛起引爆MCU市场
机器视觉有助于解决什么问题
开发者案例:动手做一个 4 孔插座,顺便搞懂智能产品开发
道相同、谋相通、人相守:华为副总裁周跃峰分享如何与用户精英共创数字基建
iPhone 12将升级新的主板,并采用4000mAh大容量电池
嵌入式开发C语言中的uint8_t科普
Wind River VxWorks支援Sprint 提升微蜂巢式无线行动通讯品质
三星S11或将采用120Hz刷新率显示屏
联发科逆袭:智能手机芯片出货量1年增长11倍
大幅面扫描仪技术术语:阈值
为了提升屏占比,各大手机厂商使出浑身解数
GE以数字化推动民航智慧化未来
聚焦新光源 推动LED行业发展
小米Max2样张露出全新Air Book互联网笔记本热卖!