字符编码总结

来源:互联网 发布:java冒泡排序算法代码 编辑:程序博客网 时间:2024/06/06 17:58

一.字符集
什么是字符集:是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
二.编码
何为编码?
是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。
解码:则是一个相反的操作。用某种方式编码,就需要用哪种方式解码。
三.编码方式
ASCII编码:ASCII编码是只支持英文的编码,是单字节编码方式,第一位置0,低7位用来编码,后七位的每个数字代码对应一个字符。
ANSI编码:ASCII编码只支持英文,随着越来越多的国家使用计算机,采用单字节编码的ASCII编码没有足够的字节状态来表示其他国家的字符了。这个时候就出现了一种双字节编码规范:ANSI编码。使用两个字节对应一个字符。而 原有的ASCII编码对应的字符不变,依旧是一个字节对应一个字符。
在这里,我们可以把ANSI编码看成一种规范:规定两个字节对应一个字符。
而不同的国家和地区有着不同的实现标准。
像对应GB2312(简体中文)字符集时,就采用GB2312编码,通常一个字符集有着其对应名字的一种编码方式。这种编码方式用两个连着的字节状态大于127的字节代表一个汉字,并且用两个字节将原来的ASCII编码编码好的字符重新编码,这些被重新编码的字符叫作全角字符,而之前用ACSII 编码的字符叫半角字符。
但是GB2312字符集并不能涵盖中文所有字符,还有很多的繁体字和生僻字么有被编码,所以又出现了GBK编码方式,该编码方式规定只要两个字节中的第一个字节大于127,低字节并没有限制,不需要是127之后的内码就可以对应一个字符。这样就又使得很多中文繁体字可以被表示。
后来,少数民族也需要使用电脑,所以又产生了新的编码方式,GB18030,包括了GBK。
而对于日文,也有其对应的ANSI编码方式,JIS。繁体字 ,BIG5.
不同国家地区的ANSI编码并不兼容。当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
Unicode编码:
为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。
在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS,Double Byte Character System)
注意:Unicode是字符集,不是一种编码方式
Unicode有多种编码方式
最常用的是UTF-8 它兼容ASCII码。
UTF-8是不定长编码
UTF-16 UTF-16 等同USC-2(即存放的是每个字符在UNICODE字符集中的序号)
四.编码方式比较以及需要注意的问题
这里写图片描述
这里写图片描述

  1. Unicode与UTF-8之间的转换
    通过上一节的例子,可以看到“严”的Unicode码是4E25,UTF-8编码是E4B8A5,两者是不一样的。它们之间的转换可以通过程序实现。
    在Windows平台下,有一个最简单的转化方法,就是使用内置的记事本小程序Notepad.exe。打开文件后,点击“文件”菜单中的“另存为”命令,会跳出一个对话框,在最底部有一个“编码”的下拉条。

里面有四个选项:ANSI,Unicode,Unicode big endian 和 UTF-8。
1)ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。
2)Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。这个选项用的little endian格式。
3)Unicode big endian编码与上一个选项相对应。我在下一节会解释little endian和big endian的涵义。
4)UTF-8编码,也就是上一节谈到的编码方法。
选择完”编码方式“后,点击”保存“按钮,文件的编码方式就立刻转换好了。
7. Little endian和Big endian
上一节已经提到,Unicode码可以采用UCS-2格式直接存储。以汉字”严“为例,Unicode码是4E25,需要用两个字节存储,一个字节是4E,另一个字节是25。存储的时候,4E在前,25在后,就是Big endian方式;25在前,4E在后,就是Little endian方式。
这两个古怪的名称来自英国作家斯威夫特的《格列佛游记》。在该书中,小人国里爆发了内战,战争起因是人们争论,吃鸡蛋时究竟是从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。为了这件事情,前后爆发了六次战争,一个皇帝送了命,另一个皇帝丢了王位。
因此,第一个字节在前,就是”大头方式“(Big endian),第二个字节在前就是”小头方式“(Little endian)。
那么很自然的,就会出现一个问题:计算机怎么知道某一个文件到底采用哪一种方式编码?
Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做”零宽度非换行空格“(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。
如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。
8. 实例
下面,举一个实例。
打开”记事本“程序Notepad.exe,新建一个文本文件,内容就是一个”严“字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8编码方式保存。
然后,用文本编辑软件UltraEdit中的”十六进制功能“,观察该文件的内部编码方式。
1)ANSI:文件的编码就是两个字节“D1 CF”,这正是“严”的GB2312编码,这也暗示GB2312是采用大头方式存储的。
2)Unicode:编码是四个字节“FF FE 25 4E”,其中“FF FE”表明是小头方式存储,真正的编码是4E25。
3)Unicode big endian:编码是四个字节“FE FF 4E 25”,其中“FE FF”表明是大头方式存储。
4)UTF-8:编码是六个字节“EF BB BF E4 B8 A5”,前三个字节“EF BB BF”表示这是UTF-8编码,后三个“E4B8A5”就是“严”的具体编码,它的存储顺序与编码顺序是一致的。

(1)BOM的来历

为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE(U+FEFF)字符开头。这作为一个“特征符”或“字节顺序标记(byte-order mark,BOM)”来识别文件中使用的编码和字节顺序。

(2)不同的系统对BOM的支持

因为一些系统或程序不支持BOM,因此带有BOM的Unicode文件有时会带来一些问题。

①JDK1.5以及之前的Reader都不能处理带有BOM的UTF-8编码的文件,解析这种格式的xml文件时,会抛出异常:Content is not allowed in prolog。“对于解决方法,之后我会写篇文章专门讨论该问题。”

②Linux/UNIX 并没有使用 BOM,因为它会破坏现有的 ASCII 文件的语法约定。

③不同的编辑工具对BOM的处理也各不相同。使用Windows自带的记事本将文件保存为UTF-8编码的时候,记事本会自动在文件开头插入BOM(虽然BOM对UTF-8来说并不是必须的)。而其它很多编辑器用不用BOM是可以选择的。UTF-8、UTF-16都是如此。

(3)BOM与XML

XML解析读取XML文档时,W3C定义了3条规则:

**①如果文档中有BOM,就定义了文件编码;
②如果文档中没有BOM,就查看XML声明中的编码属性;
③如果上述两者都没有,就假定XML文档采用UTF-8编码。**

6.2 决定文本的字符集与编码

软件通常有三种途径来决定文本的字符集和编码。

(1)对于Unicode文本最标准的途径是检测文本最开头的几个字节。如:

开头字节 Charset/encoding
EF BB BF    UTF-8
FE FF     UTF-16/UCS-2, little endian(UTF-16LE)
FF FE     UTF-16/UCS-2, big endian(UTF-16BE)
FF FE 00 00  UTF-32/UCS-4, little endian.
00 00 FE FF  UTF-32/UCS-4, big-endia

误解:“Java 中,怎样知道某个字符串的内码?”

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符串,不是 ANSI 字符串。我们只需要把字符串作为“抽象的符号的串”来看待。因此不存在字符串的内码的问题。

0 0
原创粉丝点击