手摸手带你理解 进制 字节 ASCII码 Unicode 与 字节编码(UTF-8 /16)等(下)

Jamina ·
更新时间:2024-11-13
· 996 次阅读

手摸手带你理解 进制 字节 ASCII码 Unicode 与 字节编码(UTF-8 /16)等(上)

Unicode

先讲讲这个东西的规则

Unicode 通常(不是所有)用两个字节来表示 一个字符 也就是 十六个字元(二进制数) 来表示一个字符
那原先 ASCII码定好的怎么办,已经很多机器使用了啊,假如改了可怎么办?
没有关系 Unicode 说:你只要把用不上的都补位成 0 就好了,
就比如说

01000001 在 ASCII 码里表示 大写字母 'A' 那你就补0 补成 00000000 01000001

Unicode 这玩意可是要统一所有编码的,那自然会有很多不同的语言要收录,都放一起也不方便找,
所以Unicode 就把要收录的 字符 给分组存放,用于存放不同类型的符号, 于是分了 17组,
也就是

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000 至
0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个。

码位就是放符号的地方,可以看到 Unicode 分的平面 非常的多 , 而实际上 目前用的平面很少,就已经收录了全世界大部分的字符了.

好继续讲这玩意的由来

上文讲到 ,因为 计算机交流圈越来越大,需要被纳入的字符 越来越多 .
因为你想啊,英文总共就26个字母,加上多少的符号,
而光是中文汉字 就得 好几万了 那一百来个字符咋表示的完,
然后又出现了各个国家指定自己的标准来使用的情况 就比如中国的GB2312标准 就是用来把ASCII码以外的字符加进去的.
这样一来世界的编码交流又混乱了
这时 就有两个组织都开始各自想办法去制定一套 能够容纳世界上所有字符的 编码
分别是 国际标准化组织(ISO),还有 由许多软件制造商共建的 统一码联盟

国际标准化组织(ISO),试图制定一份 通用字符集”(Universal Character Set,简称UCS),并最终制定出了 ISO 10646标准。
统一码联盟 制定出了Unicode (这个Unicode是1.0,后续会讲到,和我们的主题Unicode 的区别)

暂时先不用去理解,为什么 国际标准化组织 试图制定 通用字符集(UCS)却推出了 ISO 10646

大概知道 统一码联盟 推出了Unicode 1.0 ,国际标准化组织推出了 ISO 10646 就行了

这两套编码推出的目的 就是为了解决 世界上 的字符太多 而现有编码不够用的问题.

直到 1991 年 前后 ,这俩组织还在各自研究着 自己的编码集,但是他们拍了拍自己的秃头,好像意识到了什么,

世界上为什么需要两套能够容纳世界上所有字符而且不兼容的编码呢?

于是他们俩开始合并自己的工作成果 ,要合并也行,双方谁也不想吃亏啊,难道你希望自己家辛辛苦

苦种的西瓜被别人偷了去 吗? 那肯定不行啊,那咱商量商量呗,找个折中的办法.

从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO
10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致。两个项目仍都存在,并独立地公布各自的标准。

这就是他们找的折中的办法 , 我们慢慢说道说道

从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;

啥意思呢?大致就是
统一码联盟说 : “咱俩既然要一起干大事,不能用俩名啊,
Unicode(统一码,万国码),你康康这名儿,多威武霸气,不比你那啥ISO好听多了,不知道的还能给你拼成 iOS 那可不好是吧?”

国际标准化组织说:“也中啊! 你的名儿确实好听点,可是我的劳动成果你不能给我整没了啊,你得把我编好的不能改,放进你的编码集,里边儿去.”

统一码联盟想了想:“真是 ‘老乡见老乡,两眼泪汪汪’ ,中了! 我跟你用相同的字库 字码,不改你的,但是我把我的 编码库分成了 17个平面 , U+10FFFF前的你继续用以后不许加到再后面的平面了,后面的我要留着”

U+10FFFF: 第十个平面的最后一个 U+ 就是Unicode 的前缀,10 就是第一个平面 后面的是码位,
FFFF是最后一位 ,上文的意思就是 国际化标准化组织 以后制定的不能再超过第十个平面了.

国际化标准组织说了一句 :“中!”

这事儿就这么定了下来 , 两个项目仍都存在,并独立地公布各自的标准,但是他们有了一个响亮的新名字 Unicode !

讲完Unicode 开始 讲

UFT - 8 (16/32)

上面讲的Unicode 也好,ASCII码也好,那都是定义的字符集,就类似于,
我规定 00001 代表 汉字 ,都是一种规定,

就像我们日常说话得打标点符号把, 这个 UTF-8 UFT-16 UTF-32 就是 针对Unicode 字符集 来规定什么时候打标点的.

上文已经讲到 Unicode 的编码 通常都是两个字节的,但是也有别的字符占了更多字节的,或者更少字节的

我们先定一个规定

0000 0001 代表我在吃饭 1000 0101 1010 1000 0000 0000 0010 0001 代表我在洗澡

比如说 UTF-32 它的编码固定占用4个字节 也就是 32个位元 那它去表达 我在洗澡的时候就很容易啊,

直接说 1000 0101 1010 1000 0000 0000 0010 0001 就表示了我在洗澡,
那它想要表达我在吃饭,怎么办,一样去读啊,
一读 0000 0001 不对啊 我只能读固定的 32 位元的 你这个少了 24个啊 ,
那怎么办? 我就给你 填几个零吧 然后读出来就变成了

0000 0000 0000 0000 0000 0000 0000 0001

然后返回出来 ,我的天 ,明明只有1个字节的你给读了这么多零出来,在那个性能不是很高的年代,这种方式 是极度浪费资源的,所以他就需要换一种编码集来 读这个 这样才能最大度的利用性能,

再打个比方 我们用UTF-8 去读 0000 0001 轻轻松松就读出来 我在吃饭,
可是 它要是去读 我在洗澡,
我们来猜一下他是怎么想的,
先按照我的正常的格式去读,读个八位出来 1000 0101,咦?好像这个字还没读完?那我再读一次!1000 0101 1010 1000 ,啥?还没读完 ???
看我继续发力! 1000 0101 1010 1000 0000 0000,依旧没读完??我的吗太长了吧,再读!!
长叹一口气:啊!终于读完了!你要的编码!拿去拿去! 1000 0101 1010 1000 0000 0000 0010 0001

可以看到UTF-32 一次就能读完的文字 UFT-8却需要 读4次,这也是一种资源的浪费,

所以 不是 一次读的越多越好 而是合适,虽然,在我们这个性能过剩的年代,这些编码格式对性能的消耗 也还是很大的

现在大家应该能够理解 了 UTF-32 UFT-16 和 UTF-8

虽然我们现在通用的较多的还是UTF-8 但是选择最合适的才能对性能做到更大的提升

(虽说大部分时候最合适的还是UTF-8)

还有两个概念就是 UCS-2、UCS-4 这个UCS是不是很眼熟 没错就是上文中讲到的

国际标准化组织(ISO),试图制定一份 通用字符集”(Universal Character Set,简称UCS),并最终制定出了 ISO 10646标准。

与 UFT-8 UTF-16等相同的就是 UCS-2 UCS-4 就是 针对 ISO 10646 制定的编码格式
不过 不同的是 UFT- 后面的数字 代表了一次读多少字元,比如 UFT-8表示,一次读8个字元,
而 UCS- 后面的数字代表 一次读多少字节 (1字节=8字元)

那么我们很容易理解

UCS-2 其实与 UTF-16 是相同的 只是针对的平面不同( 毕竟不是一个标准的)
UCS-4 和 UTF-32 同理

故 在此不再赘述

最后附上

UTF-8 UTF-16 UTF-32 UCS-2 UCS-4 对比表


对比表转载自: https://www.cnblogs.com/malecrab/p/5300503.html

参考资料 : 维基百科[Unicode]


作者:Arencn.



编码 ascii码 进制 unicode ascii

需要 登录 后方可回复, 如果你还没有账号请 注册新账号