首页 > 其他分享 >[转帖]细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4

[转帖]细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4

时间:2024-01-23 18:23:05浏览次数:32  
标签:编码 UCS 字节 16 Unicode UTF

https://www.cnblogs.com/malecrab/p/5300503.html

 

1. Unicode与ISO 10646

全世界很多个国家都在为自己的文字编码,并且互不想通,不同的语言字符编码值相同却代表不同的符号(例如:韩文编码EUC-KR中“한국어”的编码值正好是汉字编码GBK中的“茄惫绢”)。因此,同一份文档,拷贝至不同语言的机器,就可能成了乱码,于是人们就想:我们能不能定义一个超大的字符集,它可以容纳全世界所有的文字字符,再对它们统一进行编码,让每一个字符都对应一个不同的编码值,从而就不会再有乱码了。

如果说“各个国家都在为自己文字独立编码”是百家争鸣,那么“建立世界统一的字符编码”则是一统江湖,谁都想来做这个武林盟主。早前就有两个机构试图来做这个事:
(1) 国际标准化组织(ISO),他们于1984年创建ISO/IEC JTC1/SC2/WG2工作组,试图制定一份“通用字符集”(Universal Character Set,简称UCS),并最终制定了ISO 10646标准。
(2) 统一码联盟,他们由Xerox、Apple等软件制造商于1988年组成,并且开发了Unicode标准(The Unicode Standard,这个前缀Uni很牛逼哦---Unique, Universal, and Uniform)。

1991年前后,两个项目的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致。两个项目仍都独立存在,并独立地公布各自的标准。不过由于Unicode这一名字比较好记,因而它使用更为广泛。

Unicode编码点分为17个平面(plane),每个平面包含216(即65536)个码位(code point)。17个平面的码位可表示为从U+xx0000到U+xxFFFF,其中xx表示十六进制值从0016到1016,共计17个平面。

2. UTF-32与UCS-4

在Unicode与ISO 10646合并之前,ISO 10646标准为“通用字符集”(UCS)定义了一种31位的编码形式(即UCS-4),其编码固定占用4个字节,编码空间为0x00000000~0x7FFFFFFF(可以编码20多亿个字符)。

UCS-4有20多亿个编码空间,但实际使用范围并不超过0x10FFFF,并且为了兼容Unicode标准,ISO也承诺将不会为超出0x10FFFF的UCS-4编码赋值。由此UTF-32编码被提出来了,它的编码值与UCS-4相同,只不过其编码空间被限定在了0~0x10FFFF之间。因此也可以说:UTF-32是UCS-4的一个子集

3. UTF-16与UCS-2

除了UCS-4,ISO 10646标准为“通用字符集”(UCS)定义了一种16位的编码形式(即UCS-2),其编码固定占用2个字节,它包含65536个编码空间(可以为全世界最常用的63K字符编码,为了兼容Unicode,0xD800-0xDFFF之间的码位未使用)。例:“汉”的UCS-2编码为6C49。

但俩个字节并不足以正真地“一统江湖”(a fixed-width 2-byte encoding could not encode enough characters to be truly universal),于是UTF-16诞生了,与UCS-2一样,它使用两个字节为全世界最常用的63K字符编码,不同的是,它使用4个字节对不常用的字符进行编码。UTF-16属于变长编码。

前面提到过:Unicode编码点分为17个平面(plane),每个平面包含216(即65536)个码位(code point),而第一个平面称为“基本多语言平面”(Basic Multilingual Plane,简称BMP),其余平面称为“辅助平面”(Supplementary Planes)。其中“基本多语言平面”(0~0xFFFF)中0xD800~0xDFFF之间的码位作为保留,未使用。UCS-2只能编码“基本多语言平面”中的字符,此时UTF-16与UCS-2的编码一样(都直接使用Unicode的码位作为编码值),例:“汉”在Unicode中的码位为6C49,而在UTF-16编码也为6C49。另外,UTF-16还可以利用保留下来的0xD800-0xDFFF区段的码位来对“辅助平面”的字符的码位进行编码,因此UTF-16可以为Unicode中所有的字符编码。

UTF-16中如何对“辅助平面”进行编码呢?

Unicode的码位区间为0~0x10FFFF,除“基本多语言平面”外,还剩0xFFFFF个码位(并且其值都大于或等于0x10000)。对于“辅助平面”内的字符来说,如果用它们在Unicode中码位值减去0x10000,则可以得到一个0~0xFFFFF的区间(该区间中的任意值都可以用一个20-bits的数字表示)。该数字的前10位(bits)加上0xD800,就得到UTF-16四字节编码中的前两个字节;该数字的后10位(bits)加上0xDC00,就得到UTF-16四字节编码中的后两个字节。例如:
(这个字念啥?^_^)
上面这个汉字的Unicode码位值为2AEAB,减去0x10000得到1AEAB(二进制值为0001 1010 1110 1010 1011),前10位加上D800得到D86B,后10位加上DC00得到DEAB。于是该字的UTF-16编码值为D86BDEAB(该值为大端表示,小端为6BD8ABDE)。

4. UTF-8

从前述内容可以看出:无论是UTF-16/32还是UCS-2/4,一个字符都需要多个字节来编码,这对那些英语国家来说多浪费带宽啊!(尤其在网速本来就不快的那个年代。。。)由此,UTF-8产生了。在UTF-8编码中,ASCII码中的字符还是ASCII码的值,只需要一个字节表示,其余的字符需要2字节、3字节或4字节来表示。

UTF-8的编码规则:

(1) 对于ASCII码中的符号,使用单字节编码,其编码值与ASCII值相同(详见:U0000.pdf)。其中ASCII值的范围为0~0x7F,所有编码的二进制值中第一位为0(这个正好可以用来区分单字节编码和多字节编码)。

(2) 其它字符用多个字节来编码(假设用N个字节),多字节编码需满足:第一个字节的前N位都为1,第N+1位为0,后面N-1 个字节的前两位都为10,这N个字节中其余位全部用来存储Unicode中的码位值。

字节数UnicodeUTF-8编码
1 000000-00007F 0xxxxxxx
2 000080-0007FF 110xxxxx 10xxxxxx
3 000800-00FFFF 1110xxxx 10xxxxxx 10xxxxxx
4 010000-10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5. 总结

(1) 简单地说:Unicode属于字符集,不属于编码,UTF-8、UTF-16等是针对Unicode字符集的编码。

(2) UTF-8、UTF-16、UTF-32、UCS-2、UCS-4对比:

对比UTF-8UTF-16UTF-32UCS-2UCS-4
编码空间 0-10FFFF 0-10FFFF 0-10FFFF 0-FFFF 0-7FFFFFFF
最少编码字节数 1 2 4 2 4
最多编码字节数 4 4 4 2 4
是否依赖字节序

参考:

本系列文章包括:

转载请注明出处:http://www.cnblogs.com/malecrab/p/5300503.html

标签:编码,UCS,字节,16,Unicode,UTF
From: https://www.cnblogs.com/jinanxiaolaohu/p/17983101

相关文章

  • Jenkins+基础系列16:番外篇--Manage and Assign Roles 角色权限控制插件
    摘自:https://blog.csdn.net/yangj507/article/details/1080832721、下载插件:Role-basedAuthorizationStrategy,安装成功后,可以重启下 2、菜单查看 3、菜单简介 4、ManageRoles设置5、AssignRoles设置 6、视图名称和job名称设置由于我们采用了表达式匹配......
  • .Net 中实体类转换为XML字符串, 确保字符串头部是utf-8 不是utf-16
    使用Utf8StringWriter或类似的方法来确保在序列化过程中使用正确的编码。然而,Utf8StringWriter不是.NETCore或.NETStandard库的一部分,因此你需要自己实现一个。不过,有一种更简单的方法可以达到相同的效果,那就是使用StringWriter与Encoding.GetEncoding("utf-8")结合,但这实际上......
  • 梦想绘图网页CAD(在线CAD插件)功能更新(2024.01.16)
    一、DEMO和下载地址:H5在线DEMO:https://demo.mxdraw3d.com:3000/mxcad/下载地址:https://www.mxdraw.com/ndetail_40255.html二、更新内容1.增加对OLE,IMAGE,外部参照的支持2.增加自定义实体功能3.支持天正格式(仅Windows系统)4.写扩展记录,对扩展字典的支持5.得到命名字典6.添加文......
  • 2024新版Windows 11要来了!16GB内存需求引热议 只是推荐配置
    最近,TrendForce集邦咨询的一份报告指出,微软已经将AIPC的内存基线设置为16GB。有媒体表示,这也意味着,新版Windows11的AI功能需要至少16GB内存才能运行。消息曝光后引发热议。对此,WC报道称,微软尚未就上述内存需求发表官方评论。16GB内存很可能只是微软的推荐配置,而非最低配置要求......
  • SQL 2016 AlwaysOn 无域AlwaysOn配置要点
    环境准备:(1)操作系统:WindowsServer2016Datacenter (2)SQLServer2016  配置SQL 2016AlwaysOn要点  1,因为没有域所以需要在”计算机属性“添加计算机的DNS后缀。如后缀是:kk1.com  2,非账户Administrator(是管理员组的新账号也不行),需在运行下列命令以管理员方式运行Po......
  • CodeForces 1609G A Stroll Around the Matrix
    洛谷传送门CF传送门我独立做出一道*3000?考虑对于单次询问,除了\(O(nm)\)的dp,有没有什么方法能快速算出答案。发现若\(a_{i+1}-a_i<b_{j+1}-b_j\)则\(i\getsi+1\),否则\(j\getsj+1\)是最优的。这个贪心的证明不难,考虑当前新走到某一行或某一列的贡献......
  • (16)Powershell中的转义字符
    (16)Powershell中的转义字符转义字符用于对其后的字符给出特殊解释。Powershell中的转义字符是反引号(`),也称为抑音符(ASCII96)。它可用于指示文本(变量名不替换为变量值,直接输出)、行继续(还有后续输入)和特殊字符。1.指示文本(变量名直接输出,不替换为变量值)当转义字符......
  • CodeForces 1609F Interesting Sections
    洛谷传送门CF传送门看到\(\max,\min\)考虑单调栈。枚举右端点,计算有多少个符合条件的左端点。单调栈维护的是对于每个右端点,以每个点为左端点的后缀\(\max,\min\)形成的极长的段。先枚举\(\text{popcount}=k\),然后如果一个段的\(\max\)的\(\text{popcount}=k\)......
  • Intel Arrow Lake处理器还是8+16 24核心:接口换LGA1851
    Intel已经确认,将在今年内发布未来两代处理器ArrowLake、LunarLake,其中前者将弥补MeteorLake的不足,同时用于笔记本、桌面、服务器,现在它的核心规格流出了。这份曝光的材料再次证实,MeteorLake原本确实规划了桌面版,只是因为性能不达标而取消,ArrowLake则早就内部排序好了叫做15......
  • AT_arc169_a的题解
    关于我在赛场上一题都没有切,后面自己推出来正解这件事~题面翻译给定一个长度为\(N\)的整数序列\(A=(A_1,A_2,\cdots,A_N)\)和另一个长度为\(N-1\)的整数序列\(P=(P_2,\cdots,P_N)\)。注意\(P\)的索引从\(2\)开始。对于每个\(i\),保证\(1\leqP_i<i\)。现在您......