字符编码

1、什么是字符编码?


  我们知道,计算机数据只能是二进制的,数值类型的数据转换成二进制很简单,我们已经了解了,但字符类型如何转换成二进制呢?这就需要使用字符编码!

  在编码表中,每个字符都有对应的编码,编码是整数,最终在计算机中存储的是字符的编码,而不是字符本身(因为计算机数据都是二进制数值,所以字符本身是无法存储的)。

  当我们存储字符’A’时,其实是通过编码表找到’A’字符对应的编码,然后把编码存储在计算机中。即存储的是65。当我们读取字符时,其实读取的也是字符的编码,然后使用编码再去编码表中查找对应的字符显示。如下:


2、常见的字符编码

(1)ASCII

  在所有字符集中,最知名的可能要数被称为ASCII的7位字符集了。它是美国标准信息交换代码(American Standard Code for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(退格、响铃等)组成。

(2)ISO-8859-1

  由于ASCII是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。有一种8位字符集是ISO 8859-1Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,起初称为拉丁码,后来被ISO(国际标准化组织)命名为ISO-8859-1。

(3)GB2312、GBK、GB18030

  GB2312是一个简体中文字符集的中国国家标准,全称为《信息交换用汉字编码字符集•基本集》,又称为GB0,由中国国家标准总局发布,1981年5月1日实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。

  GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,GB 2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。

  对于人名、古汉语等方面出现的罕用字,GB2312不能完全包括,于是对其进行了扩展,增加一些生僻字,形成了GBK。后来在GBK的基础上又增加了一些生僻字,就是GB18030。所以说,GB18030包括GBK,GBK包括GB2312。

  GB2312兼容ASCII码,这部分还是每个字符占1个字节。每个汉字字符占2个字节。GB2312是中国自己的字符集,而其他国家也都有自己的字符集!!!

(4)Unicode

  很多国家针对自己的语言都拥有自己的字符编码,那么不同编码形式进行交互时就有可能导致不兼容,如果我们打开一份字节序文件,如果不知道其编码规则,就无法正确解析其语义,这也是产生乱码的根本原因。于是有人就想将世界上的字符全部统一在一个编码表中,这就出现了Unicode编码。

  Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的编码,以满足跨语言、跨平台进行文本转换、处理的要求。它通过增加一个高字节(2个字节)对ISO Latin-1字符集进行扩展,当这些高字节位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚象形汉字和韩国象形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic 文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform之类的古老文字。Unicode支持ISO Latin-1(ISO-8859-1),而Latin-1包含了ASCII编码表。

  记住:Unicode是一个统一的编码规范,UTF-8是Unicode的一种实现方式,Unicode的实现方式除了UTF-8还有其它的,比如UCS-2和UTF-16等,它们之间能够互相转换。

3、Unicode 下的几种实现方式

(1)UTF-8

  最初的unicode编码是固定长度的,16位,也就是2两个字节代表一个字符,这样一共可以表示65536个字符。显然,这样要表示各种语言中所有的字符是远远不够的。Unicode4.0规范考虑到了这种情况,定义了一组附加字符编码,附加字符编码采用2个16位来表示,这样最多可以定义1048576个附加字符,目前unicode4.0只定义了45960个附加字符。

  事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-7.5, UTF-8, UTF-16, 以及 UTF-32。

  话说当初大牛Ben Thomson吃饭时,在一张餐巾纸上,设计出了UTF-8,然后回到房间,实现了第一版的UTF-8。

  UTF-8是一种8位的unicode字符集,编码长度是可变的,并且是ASCII字符集的严格超集,也就是说ASCII中每个字符的编码在UTF-8中是完全一样的。UTF-8字符集中,一个字符可能是1个字节,2个字节,3个字节或者4个字节长。一般来说,欧洲的字母字符长度为1到2个字节,而亚洲的大部分字符则是3个字节,附加字符为4个字节长。所以说,UTF-8能对不同范围的字符使用不同长度的编码,例如ASCII 编码部分与ASCII一样,都是1个字节,而汉字部分就是3个字节。

  UTF-8的主要优点:

    对于欧洲字母字符需要较少的存储空间。

    容易从ASCII字符集向UTF-8迁移。

(2)UCS-2

  UCS-2是固定长度为16位的unicode字符集。每个字符都是2个字节,UCS-2只支持unicode3.0,所以不支持附加字符。

  UCS-2的优点:

    对于亚洲字符的存储空间需求比UTF-8少,因为每个字符都是2个字节。

    处理字符的速度比UTF-8更快,因为是固定长度编码的。

    对于windows和java的支持更好。

(3)UTF-16

  UTF-16也是一种16位编码的字符集。实际上,UTF-16就是UCS-2加上附加字符的支持,也就是符合unicode4.0规范的UCS-2。所以UTF-16是UCS-2的严格超集。UTF-16中的字符,要么是2个字节,要么是4个字节表示的。UTF-16主要在windows2000以上版本使用。

4、Unicode转换到UTF-8规则

   如果Unicode编码的16位二进制数的前9位是0, 则UTF-8编码用一个字节来表示,这个字节的首位是0,剩下的7位与原二进制数据的后7位相同。例如:

  Unicode编码:\u0061 = 00000000 01100001

  UTF-8编码: 01100001 = 0x61

   如果Unicode编码的16位二进制数的头5位是0,则UTF-8编码用2个字节来表示,首字节用110开头,后面的5位与原二进制数据去掉前5个零后的最高5位相同;第二个字节以10开头,后面的6位与原二进制数据的低6位数据相同。例如:

  Unicode编码: \u00A9 = 00000000 10101001

  UTF-8编码: 11000010 10101001 = 0xC2  0xA9

   如果不符合上述两个规则,则用3个字节表示。第一个字节以1110开头,后四位为原二进制数据的高四位,第二个字节以10开头,后六位为原二进制数据的中间6位,第三个字节以10开头,后6位为原二进制数据的低6位。例如:

  Unicode编码: \u4E2D = 01001110 00101101

  UTF-8编码: 11100100 10111000 10101101 = 0xE4 0xB8 0xAD

5、解释一下高字节和低字节

  16位是两个字节,前八位是高字节,后八位是低字节。当一个逻辑上长于一个字节的整形数据放置在内存中时(比如16位,32位,和64位的整数),计算机设计者需要考虑这些字节的存储顺序。一些设计者选择了将字节的逻辑顺序与物理顺序一致,即将逻辑上较低的字节放置在物理上较低的字节上;另一些设计者则选择了将字节的逻辑顺序与物理顺序相反,即将逻辑上较低的字节放置在物理上较高的字节上。

  ● Big-Endian 是指高字节存放在高地址,如下:

内存地址存放内容
 0x4000 
0x12
0x4001
0x34

  ● littele-Endian 指高字节存放在第地址,如下:

内存地址 
存放内容
0x4000
0x34
0x4001
0x12 

  小结:字符编码就是将字符转换为二进制编码,其中Unicode是统一的编码规范,旗下有UTF-8等多种实现方式,而乱码的出现,就是因为使用了错误的编码表造成的!!!


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值