字符编码前世今生详解,从此与“乱码”说再见!

    大家在做web开发的时候是不是经常被乱码问题所困扰?做运维的DBA,oracle数据库使用ogg时也出现过“乱码”问题吧?这的确是个让人头痛的问题,有时候调整一下字符集就解决了,有时候又出现了,本人也在开发和运维工作中遇到过多次“乱码”问题,一直懵懵懂懂,知其然不知其所以然,最近终于下定决心好好的学下字符编码,小有成果,分享给大家,如有不足之处还请多多指正,共同进步!

   那么什么是字符编码呢?这里我们将它拆分开,1、字符集   2、编码。

   字符集: 是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
   字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。

      以上为官方解释,字符集大家好理解,字符编码是不是看晕了?我说说我通俗的理解:字符编码就是把我们所有人类创建的字符,比如:“数字、字母、文字、特殊符号等”让计算机认识并且能存取,可是计算机大家都知道只认识二进制0和1,所以说需要进行编码,也就是通过约定好的一种方式将字符转化为0和1的组合保存在计算机中,目前编码方式全世界有多种多样,后面会介绍,而从计算机中取出这些字符时就需要解码,当然也是通过与编码时相同的规则取数据,如果存数和取数的编码方式不对,就会出现牛头不对马嘴或者是鸟文“*&@930*@#*7284”,呵呵,好理解吧!
     再举个例子,抗战时期,我军与日寇都需要电台,以便于发送电报给友军及时汇报战况或消息,而那个年代科技并不发达无限电台频道数量有限,有时候不得不公用一个频道发电报,这就出现了一个问题,电报内容被窃取了怎么办?所以就发明了密码本,根据己方的密码本再翻译电台里发送来的信息,就拿到了战报,而敌人则无法破解。在这里密码本就相当于我们现在说的编码规则,写入数据是按照指定的编码规则写的,则取数时就要按照约定好的编码规则取,否则就要取到“乱码”;那么,现在又不需要保密,为什么不全世界公用一种编码规则呢? 别急,下面我仔细介绍下各个编码规则

1、追溯——ASCII编码
    首先,发明计算机的人最开始肯定没想到计算机会应用的这么广泛!在目前我们大多数计算机中都是ASCII编码,通俗的解释ASCII码,就是键盘!你的键盘上这些字母数字回车特殊符号等都属于ASCII码,他可以基本上表示通用英语,可能发明计算机的人觉得这些已经足够了,于是设计了一个编码规则,规定:ASCII编码由8位表示一个字符,也就是:0000000——11111111,大小范围限定好了,然后指定了一套规则,如下:
                                
    呵呵,后面还有一张ASCII编码拓展图,我就不贴上去了,看着烦,哈哈~  其实,没什么卵用大家平时工作也不需要关心具体编码规则怎么实现的,需要记住的是:ASCII编码是远远满足不了人类需求的,因为8位的大小并不足以表达这个美好的世界上的所有事物,比如说一个我大天朝的30划的汉字。。。在这个背景下,各种的编码规则应运而生~~~~以我大天朝为例,就有GB2312GB2312GB2312-80、GBK各种编码规则和字符集,像天朝一样,当计算机传到世界各个国家时,为了适合当地语言和字符,设计和实现类似GB232/GBK/GB18030/BIG5的编码方案。这样各搞一套,在本地使用没有问题,一旦出现在网络中,由于不兼容,互相访问就出现了乱码现象。在这种环境下,伟大的unicode诞生了

2、
unicode编码/字符集
    为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。
在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS,Double Byte Character System),因此,这种方式存放的字符也被称作宽字节字符。比如,字符串 "中文123" 在 Windows 2000 下,内存中实际存放的是 5 个序号,一共10个字节。 Unicode字符集包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

3、UTF-8编码
  终于字符集统一了,那我介绍一下应用最广泛的UTF-8编码方式:
UCS-2编码(16进制)   UTF-8 字节流(二进制)
0000 - 007F         0xxxxxxx
0080 - 07FF         110xxxxx 10xxxxxx
0800 - FFFF         1110xxxx 10xxxxxx 10xxxxxx 
例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001,用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。
可见UTF-8是变长的,将Unicode编码为00000000-0000007F的字符,用单个字节来表示; 00000080-000007FF的字符用两个字节表示;00000800-0000FFFF的字符用3字节表示。因为目前为止Unicode-16规范没有指定FFFF以上的字符,所以UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。,UTF-8兼容ASCII。
总结来说:采用UTF-8编码方式,汉字占24位也就是3字节,字母数字特殊符号占8位也就是1字节。UTF-8国际通用,你要不想你的网站在国外访问时全是乱码的话,那就采用UTF-8编码吧,哈哈

4、 GB2312、GBK和GB18030 编码
   在我大天朝的网站中,使用GBK编码的还是大有人在,
(1)GB2312 
    当中国人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存,于是想到把那些ASCII码中127号之后的奇异符号们直接取消掉, 规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。这种汉字方案叫做 "GB2312"。GB2312 是对 ASCII 的中文扩展。兼容ASCII。
(2)GBK 
   但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,不得不继续把 GB2312 没有用到的码位找出来用上。后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 “GBK” 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。
 (3)GB18030 
   后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK 扩成了 GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了。 
总结来说:采用GBK编码方式,汉字和字母都是占24位2字节,如果你的网站只在国内使用并且汉字很多的情况下可以考虑使用GBK编码,可以节省存储空间;其他编码方式也很多,就不一一介绍了





来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29018063/viewspace-2072599/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29018063/viewspace-2072599/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值