了解现代编码模型

遇到过字符乱码吗?为什么会乱码?怎么解决?了解一下现代编码模型,会对你解决相关问题有所帮助。

在Unicode Technical Report (UTR) #17中,现代编码模型分为5个层次:

抽象字符集 ACR

抽象字符集,就是要编码的所有字符的集合,为现代编码模型的最底层。

如对于简单的ASCII编码,所有128个字符就是其抽象字符集。他的抽象字符表是封闭的,就是说此编码的抽象字符表不允许再添加新的符号。显然这已经不能满足现代字符编码的要求,如Unicode、UCS编码,他们的抽象字符表是开放的,允许添加新的符号。Unicode已经收录超过13万个字符,至今仍在不断增修。

通常不同编码可以相互转换。但一个编码可以显示某个字符的前提是,这些编码的抽象字符表中都包含此字符,没有那就肯定无法处理了。如ASCII编码无法显示一个汉字。

如果一个编码的抽象字符表能包罗万象一切的字符,那他就可以取代所有的编码,如Unicode。

对于不同的编码,他们抽象字符表中的字符很多是相同的。如英文26个字母同时属于ASCII、UCS、GBK编码。

编码字符集 CCS

将 ACR 中每个字符表示为1个非负整数。所有字符映射为不同的整数,由此产生了编码空间。编码空间中的一个位置称为码位(code point)。抽象字符集与码位映射即称为编码字符集。

如ASCII编码空间包含128个码位,范围是0到127。如表示大写拉丁字母 “A” 的字符被赋予整数 65、字符 “B” 是 66,等等。

Unicode编码空间分为17个字符平面(一个基本多文种平面与16个辅助平面),每个平面有65536个码位,因此Unicode共包含17 × 65536=1114112个码位。

Unicode基本多文种平面的示意图:

图片

每个写着数字的格子代表256个码位。

字符编码表 CEF

是将 CCS 的非负整数值(即码位)转换成有限比特长度的整型值(称为码元 code units)的序列。

如UTF-8把Unicode字符集的码位映射为8位长的整数(即码元)的序列,UTF-16把Unicode字符集的码位映射为16位长的整数的序列,UTF-32把Unicode字符集的码位映射为32位长的整数的序列。而这也与计算机储存整数的8、16、32位类型相一致。

如:

图片

所以,使用UTF-8最多使用4个码元(4个8位)即可编码一个Unicode字符,而UTF-16最多使用2个码元(2个16位)编码一个Unicode字符。他们都属于变长的字符编码,所以映射比较复杂,但是节约了空间。

如对于Unicode基本多文种平面中范围由 U+000000 至U+00007F 的128个ASCII字符,对于UTF-8只需一个8位码元编码,UTF-16需一个16位码元编码。

可以说明对于一个ASCII字符文本,使用UTF-8编码最节约存储空间。UTF-16比起UTF-8,好处在于大部分字符都以固定长度的一个码元表示,但UTF-16无法兼容于7位码元的ASCII编码。

UTF-8 如今已是最主流的字符编码

下图显示了使用各种字符编码的网站的百分比:

图片

来源:https://w3techs.com/technologies/overview/character_encoding

当然字符如何编码还需要综合考量,否则也不会存在这么多的代码页。如Windows中文简体系统,默认使用 ANSI/OEM 简体中文-GBK(Code Page 936)编码。

字符编码方案 CES

如汉字“你”(U+4F60)字符的UTF-8的16进制码元序列为 E4BDA0(三个码元),因为UTF-8的码元为8位及一个字节,所以一个字符的码元可以直接映射到多个字节存储空间或字节流而不要考虑顺序的问题。

而UTF-16的16进制码元序列为4F60(一个码元),UTF-16的码元为16位及二个字节。

众所周知,系统中多字节数据单元的存储、传输,存在一个顺序的问题及大端、小端的问题,这是字符编码方案要确认的。

什么是大端BE和小端LE?

大端模式:是指对于多字节数据的MSB(最高有效字节)保存在内存的低地址中,而数据的LSB(最低有效字节)保存在内存的高地址中。

小端模式:是指对于多字节数据的MSB(最高有效字节)保存在内存的高地址中,而数据的LSB(最低有效字节)保存在内存的低地址中。

在UTF-16文件的开头,都会放置一个U+FEFF字符作为字节序标记BOM (Byte Order Mark)(UTF-16 LE以 FF FE 代表,UTF-16 BE以 FE FF 代表)。U+FEFF字符在UNICODE中代表的意义是 ZERO WIDTH NO-BREAK SPACE,顾名思义,它是个没有宽度也没有断字的空白。

所以“你”,UTF-16 BE 编码存储为:

图片

UTF-16 LE 编码存储为:

图片

传输编码语法 TES

用于处理上一层次的 CES 提供的字节序列。一般其功能包括两种:

一是把字节序列的值映射到一套更受限制的值域内,以满足传输环境的限制,例如Email传输时进行Base64编码;另一是压缩字节序列的值,如LZW或者行程长度编码等无损压缩技术。

当然这一块的内容已经离字符编码有点远,就不多写了。

更多精彩内容,可关注本人微信公众号scadafaq

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

njrobin

来根Banana~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值