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

字符编码基础知识- 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来标记文本文件的编码方式的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值