字符编码基础知识- Unicode,UCS,GBK,GB2312,UTF-8

最近遇到一个Unicode和UTF-8关系比较的问题,之前在处理中文显示时也遇到过类似的问题,于是花时间学习了一下,在此做个总结归纳,借以加深理解。(本文多数内容均来自互联网,特此申明。)

一、相关概念

1、UCS/ISO 10646

ISO组织制定的国际标准ISO 10646定义了通用字符集(Universal Character Set, UCS)。UCS是所有其他字符集标准的一个超集,它保证与其他字符集是双向兼容的。就是说,如果你将任何文本字符串翻译到UCS格式,然后再翻译回原编码,你不会丢失任何信息。

ISO 10646定义了一个31位的字符集。然而,在这巨大的编码空间中,迄今为止只分配了前65534个码位(0x0000到0xFFFD)。这个UCS的16位子集称为基本多语言面(Basic Multilingual Plane, BMP)。将被编码在16位BMP以外的字符都属于非常特殊的字符(比如象形文字),且只有专家在历史和科学领域里才会用到它们。

UCS不仅给每个字符分配一个代码,而且赋予了一个正式的名字。表示一个UCS或Unicode值的十六进制数,通常在前面加上"U+",就象U+0041代表字符"拉丁大写字母A"。UCS字符U+0000到U+007F与US-ASCII(ISO

646)是一致的,U+0000到U+00FF与ISO

8859-1(Latin-1)也是一致的。从U+E000到U+F8FF,以及BMP以外的大范围的编码是为私用保留的。

2、UCS的编码格式

UCS-2,用2个byte表示一个字符,即可以表示BMP内的全部字符。

UCS-4,用4个byte表示一个字符(实际上只用了31位,最高位必须为0),可以表示所有UCS字符(0~0x10FFFF)。

UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。

UCS -4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行(rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。

group 0的plane 0被称作基本多语言面(Basic Multilingual Plane),即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。

将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。

3、Unicode

Unicode协会制定的编码机制,要将全世界常用文字都函括进去。在1.0中是16位编码,由U+0000到U+FFFF。在2.0开始抛弃了16位限制,原来的16位作为基本位平面(BMP),另外增加了16个位平面,相当于20位编码,编码范围0到0x10FFFF。

4、UTF(UCS/Unicode

Transformation Format)

1)UTF-8就是以8bit为单元对UCS/Unicode进行编码。从Unicode到UTF-8编码方式如下。

Unicode

UTF-8

U-00000000 - U-0000007F:

0xxxxxxx

U-00000080 - U-000007FF:

110xxxxx 10xxxxxx

U-00000800 - U-0000FFFF:

1110xxxx 10xxxxxx 10xxxxxx

U-00010000 - U-001FFFFF:

11110xxx 10xxxxxx 10xxxxxx

10xxxxxx

U-00200000 - U-03FFFFFF:

111110xx 10xxxxxx 10xxxxxx

10xxxxxx 10xxxxxx

U-04000000 - U-7FFFFFFF:

1111110x 10xxxxxx 10xxxxxx

10xxxxxx 10xxxxxx 10xxxxxx

xxx的位置由字符编码数的二进制表示的位填入,越靠右的x具有越少的特殊意义。只用最短的那个足够表达一个字符编码数的多字节串。注意在多字节串中,第一个字节的开头"1"的数目就是整个串中字节的数目。

例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx

10xxxxxx 10xxxxxx。将6C49写成二进制是:0110

110001 001001,用这个比特流依次代替模板中的x,得到:111001101011000110001001,即E6 B1

89。

UTF-8有以下一些特点:

与CPU字节顺序无关,可以在不同平台之间交流。

容错能力高,任何一个字节损坏后,最多只会导致一个编码码位损失,不会链锁错误(如GB码错一个字节就会整行乱码)。

UCS字符U+0000到U+007F

(ASCII)被编码为字节0x00到0x7F (ASCII兼容)。这意味着只包含7位ASCII字符的文件在ASCII和UTF-8两种编码方式下是一样的。

所有>U+007F的UCS字符被编码为一个多个字节的串,每个字节都有标记位集。因此,ASCII字节(0x00-0x7F)不可能作为任何其他字符的一部分。

表示非ASCII字符的多字节串的第一个字节总是在0xC0到0xFD的范围里,并指出这个字符包含多少个字节。多字节串的其余字节都在0x80到0xBF范围里。这使得重新同步非常容易,并使编码无国界,且很少受丢失字节的影响。

可以编入所有可能的2^31个UCS代码

UTF-8编码字符理论上可以最多到6个字节长,然而16位BMP字符最多只用到3字节长,正式的Unicode定义字符(U+0000 to U+10FFFF)最多占用4个字节。

Bigendian UCS-4字节串的排列顺序是预定的。

字节0xFE和0xFF在UTF-8编码中从未用到。

2)UTF-16:以16bit为单元对UCS/Unicode进行编码,对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。另外,UTF-16是变长码(2个或4个byte),且以双字节作为编码单位所以实际存储、传输时与CPU字序有关,因此java有区分UTF-16BE和UTF-16LE两种charset。

3)UTF-32:仅使用了Unicode范围(0到0x10FFFF)的32位编码,相当于UCS-4的子集。

5、中文国际编码

字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的BIG5。

GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。

从ASCII、GB2312到GBK,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK都属于双字节字符集(DBCS)。

2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。从汉字字汇上说,GB18030在GB13000.1的20902个汉字的基础上增加了CJK(中日韩)扩展A的6582个汉字(Unicode码0x3400

– 0x4db5),一共收录了27484个汉字。

GB18030的编码采用单字节、双字节和4字节方案。其中单字节、双字节和GBK是完全兼容的。4字节编码的码位就是收录了CJK扩展A的6582个汉字。例如:UCS的0x3400在GB18030中的编码应该是8139EF30,UCS的0x3401在GB18030中的编码应该是8139EF31。

GB 18030是中国所有非手持/嵌入式计算机系统的强制实施标准。

二、需要注意的关系

1、Unicode与UCS

ISO与Unicode协会是两个不同的组织,都试图设计统一字符集,ISO开发了ISO

10646项目,Unicode协会开发了Unicode项目。在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO

10646-1相同的字库和字码。目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode

4.1.0。ISO的最新标准是ISO

10646-3:2003。

总结起来,Unicode与ISO

10646是两个不同的标准,但定义的内容基本相同(BMP部分完全相同),所以基本可以理解为UCS

= Unicode。

2、字符集与编码格式

ASCII、GB2312、GBK、UCS、Unicode这些都是字符集。字符集定义了字符编码表,即规定了整数到字符的对应关系,但并没有规定与这些整数如何表示、保存、传输,这些是由编码格式规定的。例如“汉”字的UCS/Unicode编码是6C49,你可以用4个ascii数字来传输、保存这个编码;也可以用utf-8编码:3个连续的字节E6

B1 89来表示它。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO-8859-1完全兼容。UTF是“UCS/Unicode

Transformation Format”的缩写。

3、big

endian和little

endian

big endian和little

endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big

endian。如果将49写在前面,就是little endian。

我们一般将endian翻译成“字节序”,将big

endian和little endian称作“大尾”和“小尾”。

三、问题回答

1、Unicode与UTF什么关系?UTF-8和UTF-16的区别是什么,为什么会有不同的UTF编码,分别适用于什么场景?

Unicode与UTF的关系不用多说,一个是字符集,一个是编码方式。

UTF-16我理解更适合程序在内存中表示字符、操作字符,因为每个字符都是2个字节的,便于cpu处理,效率高。

UTF-8更适合作为存储和网络传输的编码方式,是由其特点决定的,一是容错性好;二是每个字符的字节数可以由第一个字节开头的“1”的个数确定,方便判断字符的结束;三是UTF-8是以字节为单位编码的,不存在与cpu相关的字节序的问题;四是UTF-8处理ASCII字符有优势,只用1个字节,省空间,当然这个优势在处理中文等多字节字符时是没有的。

2、使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode

big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode

big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?

UTF -8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill

Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

在UCS编码中有一个叫做”ZERO

WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符”ZERO

WIDTH NO-BREAK SPACE”。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符”ZERO

WIDTH NO-BREAK SPACE”又被称作BOM。

UTF -8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO

WIDTH NO-BREAK SPACE”的UTF-8编码是EF

BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Windows就是使用BOM来标记文本文件的编码方式的。

计算机ucs汉字编码,字符编码基础知识 - Unicode,UCS,GBK,GB2312,UTF-8相关推荐

  1. GB2312、GBK、BIG5、Unicode及字符编码基础知识

    GB2312.GBK.BIG5.Unicode及字符编码基础知识 在搜狗的设置里面有个选项,要用户选择使用GBK还是GB2312,论坛里面常常有人要求输入法支持BIG5编码,也有人提到 Unicode ...

  2. 计算机字符编码基础知识

    计算机字符编码基础知识 由于计算机只能识别0和1,所以字符(文字.符号)需要编码,图像.音频.视频等也需要编码.本文主要介绍字符编码,特别是与机内码相关的内容. 字符的处理涉及到下列三类编码: 输入码 ...

  3. 字符编码的故事(ASCII ISO GBK GB2312 UTF-8)

    转载自:http://yuncode.net/article/a_520afe25b065d13 另有一篇对"UTF-8 GBK UTF8 GB2312 之间的区别和关系"描述比较 ...

  4. 计算机ms office 基础知识教程,计算机等级考试二级MS-Office基础知识教程.doc

    计算机等级考试二级MS-Office基础知识教程 计算机的发展.类型及其应用领域.计算机(computer)是一种能自动.高速进行大量算术运算和逻辑运算的电子设备. 速度快.精度高.存储容量大.通用性 ...

  5. 中原工学院计算机二级证书,中原工学院@计算机等级考试二级MS_Office基础知识(常考知识点记忆).doc...

    中原工学院@计算机等级考试二级MS_Office基础知识(常考知识点记忆)剖析 计算机的发展.类型及其应用领域.计算机(computer)是一种能自动.高速进行大量算术运算和逻辑运算的电子设备. 速度 ...

  6. 字符编码的知识(二)

    3.伟大的创想Unicode --不得不单独说Unicode 像天朝一样,当计算机传到世界各个国家时,为了适合当地语言和字符,设计和实现类似GB232/GBK/GB18030/BIG5的编码方案.这样 ...

  7. 字符编码ASCII、Unicode 、UTF-8 及实例汉字与Unicode码的相互转化

    字符编码ASCII.Unicode .UTF-8 及实例汉字与Unicode码的相互转化 ASCII 码 我们知道,计算机内部,所有信息最终都是一个二进制值.每一个二进制位(bit)有0和1两种状态, ...

  8. 前端需要搞懂的字符编码ASCII、Unicode、UTF8、UTF16等

    字符集和字符编码 字符集就是字符的集合,如常见的 ASCII字符集,GB2312字符集,Unicode字符集等.这些不同字符集之间最大的区别是所包含的字符数量的不同. 字符编码则代表字符集的实际编码规 ...

  9. 计算机考试一级考试基础知识,全国计算机等级考试一级msoffice基础知识

    全国计算机等级考试一级msoffice基础知识 导语:在日常生活中,媒体(Medium ,复数形式为Media )是指文字.声音.图像.动画和视频等内容.多媒体(Multimedia )是指能够同时对 ...

最新文章

  1. /org/gnome/Terminal/Factory0: Could not connec
  2. 013_JDBC模板使用第三方连接池
  3. Python语言学习:利用python语言实现调用内部命令(python调用Shell脚本)—命令提示符cmd的几种方法
  4. MYSQL [ERROR] InnoDB: Unable to lock ./ibdata1 error: 11
  5. Oracle多表连接查询
  6. String练习代码保存
  7. 飞鸽传书官方网站方式hook一些常见的枚举文件
  8. 雪城大学信息安全讲义 4.5
  9. python的返回函数的作用_函数的返回值和作用域
  10. 关于基础类数据结构的设计想法
  11. 计算机管理删除打印机驱动,彻底删除打印机驱动的方法
  12. java 如何查看文件编码_java判断文件编码 终于弄懂了编码是怎么回事
  13. 开发中接口的类型都有哪些以及如何调用?
  14. 入侵检测技术框架总论
  15. pandas入门与数据准备与简单筛选统计
  16. ctfshow-29-170
  17. 我们一起学爪哇(2)
  18. 一个大一程序员的反思
  19. 启示录:TOD分类及用地功能结构组成
  20. Debian GUN/Linux Desktop grap语言配置 [大三四八九月实习]

热门文章

  1. 关于『进击的Markdown』:第二弹
  2. 2款好用的国内翻译软件,准确率超高!
  3. vue 分页添加序号
  4. vue 动态生成二维码 qrcode
  5. POS打印机控制命令说明
  6. C/S架构与B/S架构简介
  7. 《笨兔兔的故事》之文件系统部分读书心得
  8. 比大小,人类智慧天花板,任意类型,任意个数。内容包含函数模板的创建,类的创建,动态内存的分配与释放,函数调用指针的用法。牵扯多个知识点。
  9. SQL Server 怎样使用SQL输出建表语句
  10. 微信未验证应用(微信openSDK1.8.6的集成)