编码字符集Unicode与编码方式UTF-8是个什么样的关系
对于编码字符集和编码方式隔热你理解如下图,下面的文字转载自http://blog.csdn.net/u011605971/article/details/46330087
那么这里的UTF-8、UTF-16、UTF-32都是什么意思呢
---
UTF-16比较好理解,就是任何字符对应的数字都用两个字节来保存.我们通常对Unicode的误解就是把Unicode与UTF-16等同了.但是很显然如果都是英文字母这做有点浪费.明明用一个字节能表示一个字符为啥整两个啊.
于是又有个UTF-8,这里的8非常容易误导人,8不是指一个字节,难道一个字节表示一个字符?实际上不是.当用UTF-8时表示一个字符是可变的,有可能是用一个字节表示一个字符,也可能是两个,三个.当然最多不能超过3个字节了.反正是根据字符对应的数字大小来确定.
于是UTF-8和UTF-16的优劣很容易就看出来了.如果全部英文或英文与其他文字混合,但英文占绝大部分,用UTF-8就比UTF-16节省了很多空间.而如果全部是中文这样类似的字符或者混合字符中中文占绝大多数.UTF-16就占优势了,可以节省很多空间.另外还有个容错问题,等会再讲
看的有点晕了吧,举个例子.假如中文字"汉"对应的unicode是6C49(这是用十六进制表示,用十进制表示是27721为啥不用十进制表示呢?很明显用十六进制表示要短点.其实都是等价的没啥不一样.就跟你说60分钟和1小时一样.).你可能会问当用程序打开一个文件时我们怎么知道那是用的UTF-8还是UTF-16啊.自然会有点啥标志,在文件的开头几个字节就是标志.
EF BB BF 表示UTF-8
FE FF 表示UTF-16.
用UTF-16表示"汉"
假如用UTF-16表示的话就是01101100 01001001(共16 bit,两个字节).程序解析的时候知道是UTF-16就把两个字节当成一个单元来解析.这个很简单.
用UTF-8表示"汉"
用UTF-8就有复杂点.因为此时程序是把一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把1个还是两个或三个字节做为一个单元来处理.
0xxxxxxx,如果是这样的01串,也就是以0开头后面是啥就不用管了XX代表任意bit.就表示把一个字节做为一个单元.就跟ASCII完全一样.
110xxxxx 10xxxxxx.如果是这样的格式,则把两个字节当一个单元
1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个单元.
字符集是指字符的集合,例如所有的英文字母是字符集,所有的汉字也是字符集,全世界所有语言的符号都放在一起,也可以称为一个字符集,字符集中的字符没有顺序之分,在给字符集合中的每个字符都分配一个整数编号之后,这个字符集就有了顺序,成为编码字符集。同时,根据这个编号可以唯一确定字符集中的某个字符。当然对于同一个字符,不同的编码字符集所指定的整数编号也不尽相同,例如“儿”字,在Unicode中,它的编号是0x513F(为方便起见以十六进制表示,但这个整数编号并不要求必须以十六进制表示),表示它是编码字符集Unicode中的第0x513F个字符。而在编码字符集Big5中,它就是第0xA449个字符了。许多字符在不同的编码字符集中被分配了相同的整数编号,如英文字母“A”在ASCII和Unicode中都是第0x41个字符。需要注意的是,编码字符集中字符被分配的整数编号,不一定就是该字符在计算机中存储时所用的值,计算机中存储的字符到底使用什么二进制整数值来表示,是由编码方式决定的。
一般不用二进制来表示某个字符的编码(因为不便于书写和阅读),一般采用十六进制来表示某个字符的编码。
编码方式决定了如何将一个字符的整数编码对应到一个二进制数,有的编码方式直接将该整数编码转换为二进制数存储在计算机中(如英文字符),几乎所有的编码方式中,英文字母的整数编码都与其在计算机内存储的二进制数一致。但有的编码方式,例如适用于Unicode字符集的UTF-8编码形式,就将很大一部分字符的整数编码作了变换后再存储在计算机中。以“汉”为例,“汉”的Unicode编码为6C49,但其UTF-8编码为E6B189(变成了三个字节,表示汉”是编码字符集Unicode中的第6C49个字符,将该整数编号6C49以编码方式UTF-8编码为二进制后得到E6B189)。另一种编码方式UTF-16对Unicode中的前65536个字符的编码均不做变换,直接作为计算机存储时使用的值(对65536以后的字符,仍然要做变换),如“汉”的Unicode编码为6C49,经过编码方式UTF-16编码后存储在计算机上时,它的编码仍是6C49。正是因为UTF-16的存在,使得很多人认为Unicode是一种编码方式(实际上Unicode是一种编码字符集),也因此很多人说Unicode的时候,实际上指的是UTF-16(再重申一遍,Unicode是编码方式,UTF-16是字符集,虽然内存中两者的表示方式刚好一样,但完全不是一种东西)