Java 字符的 编码 与 乱码 和恢复

本文深入探讨了字符编码的两大类:非Unicode编码和Unicode编码。非Unicode编码包括ASCII、ISO 8859-1、Windows-1252、GB2312、GBK、GB18030和Big5,详细阐述了各自的特点和适用场景。Unicode编码主要介绍了Unicode的编号体系以及UTF-32、UTF-16和UTF-8三种变长编码方式。文章还讨论了乱码产生的原因,包括解析错误和编码转换问题,并提供了乱码的解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编码有两大类:一类是非 Unicode编码;另一类是Unicode编码。我们先介绍非Unicode编码。

常见非Unicode编码

         下面我们看一些主要的非Unicode编码,包括ASCII、ISO 8859-1、 Windows-1252、GB2312、GBK、GB18030和Big5。

1.ASCII

         世界上虽然有各种各样的字符,但计算机发明之初没有考虑那么 多,基本上只考虑了美国的需求。美国大概只需要128个字符,所以就 规定了128个字符的二进制表示方法。这个方法是一个标准,称为ASCII 编码,全称是American Standard Code for Information Interchange,即美 国信息互换标准代码。

         128个字符用7位刚好可以表示,计算机存储的最小单位是byte,即 8位,ASCII码中最高位设置为0,用剩下的7位表示字符。这7位可以看 作数字0~127,ASCII码规定了从0~127的每个数字代表什么含义。

         我们先来看数字32~126的含义,如图2-1所示,除了中文之外,我 们平常用的字符基本都涵盖了,键盘上的字符大部分也都涵盖了。

在这里插入图片描述

         数字32~126表示的字符都是可打印字符,0~31和127表示一些不 可以打印的字符,这些字符一般用于控制目的,这些字符中大部分都是 不常用的,表2-4列出了其中相对常用的字符。

在这里插入图片描述
         ASCII码对美国是够用了,但对其他国家而言却是不够的,于是, 各个国家的各种计算机厂商就发明了各种各种的编码方式以表示自己国 家的字符,为了保持与ASCII码的兼容性,一般都是将最高位设置为1。 也就是说,当最高位为0时,表示ASCII码,当为1时就是各个国家自己 的字符。在这些扩展的编码中,在西欧国家中流行的是ISO 8859-1和 Windows-1252,在中国是GB2312、GBK、GB18030和Big5,我们逐个 介绍这些编码。

2.ISO 8859-1

         ISO 8859-1又称Latin-1,它也是使用一个字节表示一个字符,其中0 ~127与ASCII一样,128~255规定了不同的含义。在128~255中,128 ~159表示一些控制字符,这些字符也不常用,就不介绍了。160~255 表示一些西欧字符,如图2-2所示
在这里插入图片描述

3.Windows-1252

         ISO 8859-1虽然号称是标准,用于西欧国家,但它连欧元(€)这个 符号都没有,因为欧元比较晚,而标准比较早。实际中使用更为广泛的 是Windows-1252 编码,这个编码与ISO 8859-1基本是一样的,区别只在 于数字128~159。Windows-1252使用其中的一些数字表示可打印字符, 这些数字表示的含义如图2-3所示
在这里插入图片描述
         这个编码中加入了欧元符号以及一些其他常用的字符。基本上可以 认为,ISO 8859-1已被Windows-1252取代,在很多应用程序中,即使文 件声明它采用的是ISO 8859-1编码,解析的时候依然被当作Windows- 1252编码。

         HTML5甚至明确规定,如果文件声明的是ISO 8859-1编码,它应该 被看作Win-dows-1252编码。为什么要这样呢?因为大部分人搞不清楚 ISO 8859-1和Windows-1252的区别,当他说ISO 8859-1的时候,其实他 指的是Windows-1252,所以标准干脆就这么强制规定了。

4.GB2312

         美国和西欧字符用一个字节就够了,但中文显然是不够的。中文第 一个标准是GB2312。GB2312标准主要针对的是简体中文常见字符,包 括约7000个汉字和一些罕用词和繁体字。

          GB2312固定使用两个字节表示汉字,在这两个字节中,最高位都 是1,如果是0,就认为是ASCII字符。在这两个字节中,其中高位字节 范围是0xA1~0xF7,低位字节范围是0xA1~0xFE。

         比如,“老马”的GB2312编码(十六进制表示)如表2-5所示。

在这里插入图片描述

5.GBK

         GBK建立在GB2312的基础上,向下兼容GB2312,也就是说, GB2312编码的字符和二进制表示,在GBK编码里是完全一样的。GBK 增加了14000多个汉字,共计约21000个汉字,其中包括繁体字。

         GBK同样使用固定的两个字节表示,其中高位字节范围是0x81~ 0xFE,低位字节范围是0x40~0x7E和0x80~0xFE。

         需要注意的是,低位字节是从0x40(也就是64)开始的,也就是 说,低位字节的最高位可能为0。那怎么知道它是汉字的一部分,还是 一个ASCII字符呢?其实很简单,因为汉字是用固定两个字节表示的, 在解析二进制流的时候,如果第一个字节的最高位为1,那么就将下一 个字节读进来一起解析为一个汉字,而不用考虑它的最高位,解析完后,跳到第三个字节继续解析。

6.GB18030

         GB18030向下兼容GBK,增加了55000多个字符,共76000多个字 符,包括了很多少数民族字符,以及中日韩统一字符。

         用两个字节已经表示不了GB18030中的所有字符,GB18030使用变 长编码,有的字符是两个字节,有的是四个字节。在两字节编码中,字 节表示范围与GBK一样。在四字节编码中,第一个字节的值为0x81~ 0xFE,第二个字节的值为0x30~0x39,第三个字节的值为0x81~ 0xFE,第四个字节的值为0x30~0x39。

         解析二进制时,如何知道是两个字节还是4个字节表示一个字符 呢?看第二个字节的范围,如果是0x30~0x39就是4个字节表示,因为 两个字节编码中第二个字节都比这个大。

7.Big5

         Big5是针对繁体中文的,广泛用于我国台湾地区和我国香港特别行 政区等地。Big5包括13000多个繁体字,和GB2312类似,一个字符同样 固定使用两个字节表示。在这两个字节中,高位字节范围是0x81~ 0xFE,低位字节范围是0x40~0x7E和0xA1~0xFE。

8.编码汇总

         我们简单汇总一下前面的内容。

         ASCII码是基础,使用一个字节表示,最高位设为0,其他7位表示 128个字符。其他编码都是兼容ASCII的,最高位使用1来进行区分。

         西欧主要使用Windows-1252,使用一个字节,增加了额外128个字 符。

         我国内地的三个主要编码GB2312、GBK、GB18030有时间先后关 系,表示的字符数越来越多,且后面的兼容前面的,GB2312和GBK都 是用两个字节表示,而GB18030则使用两个或四个字节表示。

         我国香港特别行政区和我国台湾地区的主要编码是Big5。

         如果文本里的字符都是ASCII码字符,那么采用以上所说的任一编 码方式都是一样的。

         但如果有高位为1的字符,除了GB2312、GBK、GB18030外,其他 编码都是不兼容的。比如,Windows-1252和中文的各种编码是不兼容 的,即使Big5和GB18030都能表示繁体字,其表示方式也是不一样的, 而这就会出现所谓的乱码,具体我们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值