最近被字符集搞得头大,基于为自己扫盲的目的,索性收集资料研究一下,现将各方资料归纳成本文。这里并不想把复杂的规则说明一大通。如有需要,请参照其他资料或本文给出的参考资料。
如有错误,欢迎指正。
[顺便发下牢骚,je的编辑器真TMD难用,排版排得我半死]
基础知识
字节和字符
字节(octet):顾其英文名而思义,就是一个八位的存储单元,取值范围一定是0~255;
字符(character):就是一个语言上的符号,"中"字就是一个字符。字符所占的大小由其编码方式解决,比如"中"在UTF-8中占3个字节(0xE4A8AD),而在GBK中,则占两个字节(0xD6D0)。
字符集和编码
字符集:字符的集合,像Unicode字符集,目标就是收纳了这个世界上所有语言的文字、符号等;
字符编码:注意,字符集只是规定了有哪些字符,而最终决定采用哪些字符,每一个字符用多个字节表示等问题,则是由编码来决定的。像Unicode字符集的编码方式有很多,诸如UTF-8、UFT-16、UTF-32等。
字符集和字符编码是分开的概念,但有时候称呼上会有些模糊,我们经常笼统地称这些Unicode字符集的编码为Unicode编码。
内码
内码:操作系统内部的字符编码。像早期的DOS采用的是ASCII,而现在的操作系统大把采用Unicode编码。
编码简史
在讲各种编码之前,有必要先讲一个编码这个令人头疼的家伙的历史,这样有助于大家理解今天的编码世界为什么会是这样一个局面。
计算机对多语言的支持,大致为分以下三个阶段。
阶段一:ASCII时代。计算机是DOS时代的计算内码是ASCII码,ASCII的表示范围就是0到127那几个符号,这意味着,DOS时代的计算机只能显示英文,而无法支持其他语言。没办法,由于英文系国家开创了并继续主导了计算机的世界,他们自然而然地认为全世界的文字用8位表示足矣。
阶段二:ANSI时代。由于上述原因,像我们这些非英文系的国家的为了显示自家的文字,不得不一开始就得面对字符编码的问题,不同国家不同地区都创建了自己的编码标准。像是中国大陆是GB2312及后来的GBK,台湾是BIG5,日本是JIS。ASCII字符集,以及这些由此派生并兼容的字符集称为ANSI字符集。
阶段三:Unicode时代。为了和谐而出现,相较于以上两个阶段,这个时代称为国际化时代,适应了跨平台,跨语言之间交换信息的需求。
Unicode和UTF系列
Unicode
Unicode 字符集收录了这世界上所有的文字符号和特殊符号。对于每一个符号都定义了一个值,称为代码点(code point)。代码点可以用2个字节表示(UCS-2),也可以用4个字节(UCS-4编码)。
UTF系列
为什么出现UTF编码?
UCS编码虽然定义了每个代码点的编码方式,但是没规定如何传输和存储。比如,在UCS-2码中,英文符号是在ACSII码的前面加上一个0 byte,像"A"的ASCII码 0x41,在UCS码中就是0x0041,这样,对于英文系统来讲会出现大量的0 byte,造成不必要的浪费。而且容易存在对现在ASCII码不兼容的问题。所以这个重担就落在了UTF编码身上,全称是Unicode Transformation Format。
什么是Endian?
我们知道"中"字的UFT-16编码是0x4E,0x2D,但是传输存储的过程中,字节的顺序有可能是(0x4E,0x2D),也可能是(0x2D,0x4E),这就是涉及一个字节序的问题。对于前一种,我们称为Big Endian(大尾,也就是高位在前),而后一总称为Little Endian(小尾,低位在前)。
那我们如何知道在不清楚哪一"尾"的情况下进行解析?
先人已有解决的办法,就是在最前面加多2个字节,OxFEFF表示BE,而0xFFFE表示LE。(注:OxFEFF是实际上不存在的字符,所以正常情况下是不会使用到的,所以,不用担心出现与正常的字符数据冲突的问题),这就是所谓的BOM(Bill Of Material)。
UTF系列都存在LE,BE,BOM,无BOM几种版本。
比如"中国"的各个版本UTF-16字符编码如下:
编码 | 字节序列 |
UTF-16BE | 4E,2D,56,FD |
UTF-16LE | 2D,4E,fD,56 |
UTF-16(BOM,BE) | FE,FF,4E,2D,56,FD |
UTF-16(BOM,LE) | FF,FE,2D,4E,fD,56 |
UFT-8
UTF-8采用的是变长码的方式,其编码规则如下:
代码点值的范围(16进制) | 第1字节 | 第2字节 | 第3字节 |
0000 0000-0000 007F | 0xxxxxxx0-127) | | | |
0000 0080-0000 07FF | 110xxxxx (192-223) | 10xxxxxx (128-191) | |
0000 0800-0000 FFFF | 1110xxxx (224-239) | 10xxxxxx (128-191) | 10xxxxxx (128-191) | |
注:x的内容是将左边代码点的二进制值依次注入。
理论上UTF-8可以达到6个字节编码(上表省略后3位字节以上的编码方式),但实际上,我们一般只采用0x0000 0000 到0x0000 0000FFFF的范围内的字符,也就说UTF-8实际上只采用了3个字节编码。
UTF-8除了省空间和兼容ASCII的优点后,其编码方式(类似于哈夫曼编码,很容易判断出1个字节及其后面的字节数)决定了它以下两个优点:
1、与字节顺序无关, 可以在不同平台之间交流。
2、容错能力高, 任何一个字节损坏后, 最多只会导致一个编码码位损失, 不会链锁错误(如GB码错一个字节就会整行乱码)
UTF-16和UTF-32
UTF-16是变长码,大致上相当于UCS-2码的直接实现,但是也有一部分UCS-4的字符。所以可以猜到,它大部分是采用2个字节编码,而有部分特殊符号采用3字节编码,所以大致相当于20位编码, 值在0到0x10FFFF之间。
UTF-32用四个字节表示代码点,这样就可以完全表示UCS-4的所有代码点。
GB2312、GBK和 GB18030
简单来讲,这三者是这样一个关系:GB2312扩展便成了GBK,GBK扩展便成了GB18030。后者都对前者兼容。
GB2312:采用2个字节。简体字的编码规范,也包括其他的符号、字母、日文假名等,共7445个图形字符,其中汉字占6763个
GBK:采用了2个字节。GB2312明显收录的汉字不够,于是增加了大量不常用汉字,还加入了几乎所有的Big5中的繁体汉字之后便成了GBK。
GB18030:与前两者不同,采用了变长的编码方式,有1、2、4个字节的编码长度。1个字节编码与ASCII兼容,2个字节编码与GBK兼容,4个字节主要是收录了少数民族的文字等。GB18030诞生的原因类似于GBK,就是增加了大量的汉字,多收录了藏文、蒙文、维吾尔文等主要的少数民族文字。GB18030现在是国家非手持/非嵌入式设备的强制性标准。
但是GB18030与前者不同的是,所有的Unicode编码都可以转换为GB18030,而且GB18030除了兼容GBK以及Unicode的BMP部分外,其余的Unicode扩展平面和它的4字节扩展平面都是简单直接的映射
其具体映射关系的计算参见《GB18030编码研究以及GBK、GB18030与Unicode的映射》:[http://blog.csdn.net/fmddlmyy/archive/2008/04/13/2288312.aspx]
如果说GB2312、GBK是ANSI时代的产物,为什么如今还需要制定GB18030呢?以下引用官方的话:"世界许多国家和地区从方便本国和民族应用的角度出发,制定了相应的编码标准和内码体系,如日本的JIS X 0208和JIS X 0212,韩国的KS C 5601和KS C 5657等,这是国际上采用的通行惯例。制定GB 18030同样符合国际惯例,它全面兼容GB 2312,在字汇上兼容GB 13000.1,可以充分利用已有资源,保证不同系统间的兼容性,最大限度地共享资源,为我国软件产业留有巨大的发展空间。可以相信,GB 18030的实施将有利于国产软件的发展并形成规模,使我国的中文信息技术再上一个台阶。"
GB2312、GBK的编码范围如下:
名称 | 第一字节 | 第二字节 | |
GB2312 | 0xA1-0xF7(161-247) | 0xA1-0xFE(161-254) | |
GBK | 0x81-0xFE(129-254) | 0x40-0xFE(64-254) |
GB18030编码范围如下:
字节数 | 码位空间 |
单字节 | 0x00~0x7F (0-127) |
双字节 | 第一字节在0x81~0xFE (129-254)第二字节在0x40~0x7E,0×80至0×FE(64-126),(128-254) |
四字节 | 第一字节在0x81~0xFE之间 (129-254) 第二字节在0x30~0x39之间 (48-57) 第三字节在0x81~0xFE之间 (129-254) 第四字节在0x30~0x39之间 (48-57) |
ASCII和ISO 8859-1
ISO 8859-1就比较简单了,我们知道ASCII码是从0x00到0x7F,也就是还有1位没有用到,ISO 8859-1就是在空置的0xA0-0xFF的范围内,加入192个字母及符号,藉以供使用变音符号的拉丁字母语言使用。所以ISO 8859-1又称Latin-1。
其他编码
这里"编码"的含义与以上不同,并不是指字符集的编码,而是一种对文本加工处理的编制方式。因为在开发过程中,也会经常遇到,所以一并介绍。
application/x-www-form-urlencoded
我们在提交表单的时候,常常会看到形如http://localhost:6888/aomstudy/Servlet1?name=%D6%D0%B9%FA
这样的地址,这些就是application/x-www-form-urlencoded格式编码后的字符串。包括用POST提交表单内容默认是使用这种编码方式。另一种是multipart/form-data,用于有大量非ASCII码文本或二进制数据时,因为这时使用application/x-www-form-urlencoded需要大量的转换,需要耗费太多时间。
为什么需要这个application/x-www-form-urlencoded编码?我还不是很明白。个人猜测是:以下规则提到的安全字符都是7位的ASCII字符,虽然HTTP协议支持任意字符,但由于历史原因,在HTTP传输过程,只能保证这7位是安全的,也就是说不被当作其他用途,比如用作控制符等。
application/x-www-form-urlencoded的编码规则如下:
1.字母数字字符 "a" 到"z"、"A"到 "Z" 和 "0" 到"9" 保持不变。
2.特殊字符 "."、"-"、"*" 和"_" 保持不变。
3.空格字符 " " 转换为一个加号"+"。
4.所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。然后每个字节用一个包含3个字符的字符串"%xy" 表示,其中 xy 为该字节的两位十六进制表示形式。
注:以上URL中使用的是GBK编码,原文是http://localhost:6888/aomstudy/Servlet1?name=中国
Base64
介绍之前,先给一段"乱码",让我们有一个感观的认识。
u7bTrcC0tb1BcHVzaWO1xMrAvec=
是不是很眼熟?是的,在电子邮件中我们经常见到。Base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。主要应用在电子邮件技术、LDIF档案等。
Base64怎么编码?简单来讲,Base64不管你使用的是什么编码,UTF-8也好,ASCII也好,它的眼里只有二进制序列,比如说"中国"GBK编码的二进制序列是[11010110],[11010000],[10111001],[11111010]。那么接下Base64 会做以下几件事:
一、Base64按照每3个字节一组(共3*8=24位),依次编入4个字节里。
只使用低位6个位(共4*6=24位),每个字节前两位置0。值的范围在0到63。
如果不是3的倍数怎么办?就先全部补[01000000](为什么不是0?因为0是有意义的),比如上面最后一个字节[11111010]变成:[00111110],[00100000],[01000000],[01000000],解码时,由于只考虑低6位,而这个值用了第7位,所以不会影响到正常字符的解码。
最终转换后成了这样[00110101],[00101101],[00000010],[00111001],[00111110],[00100000],[01000000],[01000000]
二、根据编码的值转换成对应的ASCII字符。对应规则如下:
值 | ASCII字符 | 值 | ASCII字符 | 值 | ASCII字符 | 值 | ASCII字符 |
0 | A | 17 | R | 34 | i | 51 | z |
1 | B | 18 | S | 35 | j | 52 | 0 |
2 | C | 19 | T | 36 | k | 53 | 1 | |
3 | D | 20 | U | 37 | l | 54 | 2 | |
4 | E | 21 | V | 38 | m | 55 | 3 | |
5 | F | 22 | W | 39 | n | 56 | 4 | |
6 | G | 23 | X | 40 | o | 57 | 5 | |
7 | H | 24 | Y | 41 | p | 58 | 6 | |
8 | I | 25 | Z | 42 | q | 59 | 7 | |
9 | J | 26 | a | 43 | r | 60 | 8 | |
10 | K | 27 | b | 44 | s | 61 | 9 | |
11 | L | 28 | c | 45 | t | 62 | + | |
12 | M | 29 | d | 46 | u | 63 | / | |
13 | N | 30 | e | 47 | v | 64(pad) | = | |
14 | O | 31 | f | 48 | w | | | |
15 | P | 32 | g | 49 | x | | | |
16 | Q | 33 | h | 50 | y |
[00110101],[00101101],[00000010],[00111001],[00111110],[00100000],[01000000],[01000000]的十进制值分别经[53],[45],[2],[57],[62],[32],[64],[64],找到相应的ASCII值,最终,我们得到编码后的字符串为1tC5+g==
注:以上"乱码"原文为"欢迎来到Apusic的世界"。
常见的应用场景(以后再补充完整)
参考资料
1.《Unicode详解》:http://tech.idv2.com/2008/02/21/unicode-intro/
2.《Unicode、UCS和UTF编码简介》:http://hi.baidu.com/%D0%DB%CF%D8/blog/item/f3e0d7f221c09c12b17ec512.html
3.《GB18030编码研究以及GBK、GB18030与Unicode的映射》:http://blog.csdn.net/fmddlmyy/archive/2008/04/13/2288312.aspx
4.《汉字编码问题》:http://www.css8.cn/css8_document/gb2312.htm
5.《Java:Unicode简介》:http://tech.it168.com/oldarticle/2006-11-09/200611092313338.shtml
6.《字符,字节和编码》:http://www.regexlab.com/zh/encoding.htm
7.《ISO 8859-1》:http://baike.baidu.com/view/758577.htm
8.《Base64》:http://zh.wikipedia.org/wiki/Base64
分享到:
相关推荐
### 信道编码简介 #### 一、信道编码的重要性及历史发展 信道编码,又称差错控制编码,作为现代通信系统的核心技术之一,对于保障数据传输的准确性和可靠性至关重要。几十年的发展历程中,信道编码技术不断演进,...
国际化的字符串编码简介不仅涵盖了基本的字符编码理论,还涉及到在实际开发中如何处理编码问题。了解并熟练掌握这些知识,对于编写跨平台、跨语言的软件至关重要。在进行国际化项目时,对字符串编码的理解和应用能力...
【储存系统容错编码简介】 容错编码在存储系统中扮演着至关重要的角色,它能够确保数据在面临硬件故障或错误时仍能被正确地读取和恢复。通过使用容错编码,我们可以增强系统的可靠性和稳定性,从而解决编程中遇到的...
西里尔字符编码简介.doc 西里尔字符编码简介.doc
字符集与字符集编码简介 我们知道,计算机只能识别诸如0101这样的二进制数,于是人们必须以二进制数据与计算机进行交互,或者先将人类使用的字符按一定规则转换为二进制数。 那什么是字符呢?在计算机领域,我们把...
《各种文字编码简介》 文字编码是计算机处理和显示字符的基础,不同的编码方式适用于不同的应用场景。本文主要介绍几种常见的字符编码标准,包括ASCII、HZ、GB2312、EUC-CN、GBK、Big5以及GB18030。 ASCII码是最早...
各种文字编码简介 包括ASCII GB2312 GBK GB18030 BIG5 ISO-8859-1 UTF-16 UTF-8等
### 文字编码基础知识详解 #### 一、ASCII 编码:全球通用的英文字符编码标准 在计算机发展的早期阶段,为了能够用计算机处理文本信息,科学家们设计了一套编码方案,将所有常用的英文字符(包括空格、标点符号、...
Java字符编码是编程中至关重要的一个概念,尤其是在处理多语言数据时。本文主要探讨了Java中与字符编码相关的基础知识,包括ISO8859-1、GB2312、GBK、Unicode以及UTF编码。 首先,ISO8859-1是一种早期的单字节编码...
字符集与字符编码是计算机处理文字的基础,它们决定了如何用二进制表示各种语言的字符。在信息技术领域,理解和掌握字符集与字符编码至关重要,因为它们直接影响到数据的存储、传输和显示。以下是对这些概念的详细...
介绍视频编码的英文PPT,包括视频编码的必要性、历史、目标、理论基础、编码框架、性能比较等内容。PPT制作精美。
视频格式与压缩编码是数字媒体处理中的核心概念,它们对于现代多媒体内容的存储、传输和播放至关重要。在本文中,我们将深入探讨这两种技术,并尝试理解它们如何协同工作以实现高效的信息处理。 首先,我们来了解...
### IRIG-B编码详解 #### 一、IRIG-B编码概述 **IRIG-B**是一种由IRIG(Inter-Range Instrumentation Group)委员会定义的标准,主要用于时间同步与频率分配的应用场景。这一标准广泛应用于需要精确时间同步的系统...
网络编码是一种先进的通信技术,它改变了传统网络中数据仅沿着单一路径从源点传输到目的地的方式,通过在中间节点对数据进行编码和解码来提高网络效率和吞吐量。以下是对网络编码的详细介绍: 首先,我们如何发现...
字符编码是计算机处理文本的基础,它定义了如何将字符转换为二进制数据,以便计算机存储、处理和传输。在IT行业中,理解不同字符编码体系的重要性不言而喻,特别是Unicode、GBK和UTF-8这三种编码方式。下面将详细...
Shannon定理是信息论的基础,它阐述了在有噪声的通信信道中,通过适当的编码方式,可以实现任意低的错误率传输信息。这个定理由Claude Shannon在1948年提出,它揭示了信道容量C与编码速率R之间的关系。 信道容量C是...
### 二、字符编码简介 #### 1. ASCII(American Standard Code for Information Interchange) - **定义**:ASCII码是一种基于拉丁字母的一套电脑编码系统,用于显示现代英语和其他西欧语言。 - **特点**: - 使用...