UTF-8和Unicode

基础知识:

1. bit(位):计算机存储信息的最小单位,称之为位(bit),音译比特。二进制的一个“0”或一个“1”叫一位。

2. byte(字节):字节(byte)是一种计量单位,表示数据量多少,它是计算机信息技术用于计量存储容量的一种计量单位,8个二进制位组成1个字节。

3. char(字符):字符是指计算机中使用的文字和符号,比如“1、2、3、A、B、C、~!·#¥%…*()+”等等。

4. ASCII码:全名是American Standard Code for Information Interchange, 叫做“美国信息交换标准码”。详见以下ASCII表:

å¾çæ¥æºç¾åº¦ç¾ç§

ASCII定义了128个字符,包括33个不可打印的控制字符(non-printing control characters)和95个可打印的字符。32(十进制)以下的及最后一个127是所谓的控制字符。(0x00~0x1F以及0x7F)。

由于只定义了27=128个字符,用7bit即可完全编码,而一字节8bit的容量是256,所以一字节ASCII的编码最高位总是0。

  • 对于ASCII编码的文件,计算机每次读取一个字节,然后参照ASCII表把这些编码翻译成字符。

5. ISO-8859-1:ISO-8859-1又称Latin-1,是一个8位单字节字符集,它把ASCII的最高位也利用起来,并兼容了ASCII,它是对ASCII的扩展。新增的理论空间是128,但它并没有完全用完。详见下表:

image

上表读法:竖横的值相连接。(例如:竖=5x;横=x9,代表的字符是Y,对应的十六进制值:0x59,对应的十进制的值是:89)

ISO-8859-1 的较低部分(从 1 到 127 之间的代码)是最初的 7 比特 ASCII。

ISO-8859-1 的较高部分(从 160 到 255 之间的代码)全都有实体名称。

新增部分保留了前面的32个位置(0x80-0x9F),所以实际只增加了128-32=96个,主要是西欧的一些字符。

  • 和ASCII表类似,计算机也是每次只读一个字节,然后按照ISO表,解码出字符。

6. ANSI:严格来说,ANSI的字面意思并非字符编码,而是美国的一个非营利组织——美国国家标准学会(American National Standards Institute)的缩写。

ANSI编码是一种对ASCII码的拓展:ANSI编码用0x00~0x7f (即十进制下的0到127)范围的1 个字节来表示 1 个英文字符,超出一个字节的 0x80~0xFFFF 范围来表示其他语言的其他字符。也就是说,ANSI码仅在前128(0-127)个与ASCII码相同,之后的字符全是某个国家语言的所有字符。值得注意的是,两个字节最多可以存储的字符数目是2的16次方,即65536个字符,这对于一个语言的字符来说,绝对够了。

ANSI并不是某一种特定的字符编码,而是在不同的系统中,ANSI表示不同的编码。ANSI编码只存在于Windows系统。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码(活动页代码:CP936);在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码(活动页代码:CP932;但CP932对Shift JIS有扩展;另外,对应的微软ANSI代码页为CP943,也对Shift JIS有扩展)。在繁体中文Windows操作系统中,ANSI编码代表Big5编码(活动页代码:CP950)。
代码页一般与其所直接对应的字符集之间并非完全等同,往往因为种种原因(比如标准跟不上现实实践的需要)而会对字符集有所扩展。

不同语言之间的ANSI码之间不能互相转换,这就会导致在多语言混合的文本中会有乱码。

可以通过chcp命令临时修改当前cmd窗口的ANSI编码,例如:
(1) 执行:chcp 437,code page改为437,当前终端的默认编码就为ASCII编码了(汉字就成乱码了);
(2) 执行:chcp 936,code page改为936,当前终端的默认编码就为GBK编码了(汉字又能正常显示了)。
上面的操作只在当前终端起作用,并不会影响系统默认的“ANSI编码”。

Windows下code page是根据当前系统区域(locale)来设置的,要想修改系统默认的“ANSI编码”,可以通过修改系统区域来实现(“控制面板” =>“区域”=>“管理”=>“更改系统区域设置...”)

关于汉字编码方案的历史:

  • GB2312编码:在ASCII码的基础上,规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字。前面的一个字节(称之为高字节)从0xA1用到0xFE,后面一个字节(称之为低字节)从0xA1到0xFE。也就是说,GB2312编码范围:A1A1-FEFE其中汉字编码范围:B0A1-F7FE,这样就可以组合出大约7000多个简体汉字。在这些编码里,还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符。GB2312 是对 ASCII 的中文扩展。
  • GBK编码:后来发现,GB2312编码中的汉字不够用,于是不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。
  • GB18030编码:在GBK编码基础上,增加了几千个新的少数民族的字。

7. Unicode

为了解决不同国家ANSI编码的冲突问题,Unicode应运而生。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS,俗称为Unicode。
Unicode有两种格式:UCS-2和UCS-4。UCS-2就是用两个字节编码,一共16个比特位,这样理论上最多可以表示65536个字符,不过要表示全世界所有的字符显示65536个数字还远远不够,因为光汉字就有近10万个,因此Unicode4.0规范定义了一组附加的字符编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)。理论上完全可以涵盖一切语言所用的符号。世界上任何一个字符都可以用一个Unicode编码来表示,一旦字符的Unicode编码确定下来后,就不会再改变了。
Unicode编码是一种理论层面的东西。Unicode实际上是一个字符集,它仅仅指定了字符对应的数字,仅此而已。Unicode并不涉及字符是怎么在字节中表示的,而且对于这个二进制代码如何传输,存储以及解码也没有任何规定。它的想法很简单,就是为每个字符规定一个用来表示该字符的数字,仅此而已。

8. UTF

Unicode来到时,一起到来的还有计算机网络的兴起,Unicode如何在网络上传输也是一个必须考虑的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到UTF时并不是直接的对应,而是要过一些算法和规则来转换。

在网络里传递信息时有一个很重要的问题,就是对于数据高低位的解读方式,一些计算机是采用低位先发送的方法,例如我们PC机采用的 INTEL 架构,而另一些是采用高位先发送的方式,在网络中交换数据时,为了核对双方对于高低位的认识是否是一致的,采用了一种很简便的方法,就是在文本流开始时向对方发送一个标志符——如果之后的文本是高位在前,低位在后,那就发送"FEFF"("大头方式"(Big endian)),反之,则发送"FFFE"("小头方式"(Little endian))

Unicode 可以使用的编码有三种,分别是:

UFT-8:一种变长的编码方案,使用 1~6 个字节来存储;
UFT-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;
UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。

后面的数字表明至少使用多少个比特位(Bit)来存储字符。

只有 UTF-8 兼容 ASCII,UTF-32 和 UTF-16 都不兼容 ASCII,因为它们没有单字节编码。

8.1 UTF-8

UTF-8为了节省资源,采用变长编码,编码长度从1个字节到6个字节不等。

UTF-8 的编码规则很简单:如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

具体的表现形式为:

0xxxxxxx:单字节编码形式,这和 ASCII 编码完全一样,因此 UTF-8 是兼容 ASCII 的;
110xxxxx 10xxxxxx:双字节编码形式;
1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式;
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式。

 

 

 

转载于:https://my.oschina.net/u/3726099/blog/3051305

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值