各种字符编码详解【图文教程】

平凡也就两个字: 懒和惰;
成功也就两个字: 苦和勤;
优秀也就两个字: 你和我。
跟着我从0学习JAVA、spring全家桶和linux运维等知识,带你从懵懂少年走向人生巅峰,迎娶白富美!
关注微信公众号【 IT特靠谱 】,每一篇文章都是心得总结,跟我学习你就是大牛!

 

各种字符编码【图文教程】

      各个编码中各字符占用(字节数):

 

      Tips:上图来源于度娘某博主。

 

1 各种编码理解

(1)ASCII码:美国信息交换标准代码

      ASC II码全称是“美国信息交换标准代码”,从字面上我们就能知道,这是一套用于显示英语和西欧语种的编码体系。

      它包含常用的英文字母、数字及一些特殊字符和控制符等共计127个字符,是最通用的单字节编码系统,即一个字符对应一个唯一的ASC II码。

      随着个人计算机在全球的普及,很明显单字节的字符编码根本不能满足各个国家、各个语种的编码和显示需求,这个时候就需要针对不同语种定制不同的编码规范。GBK、GB2312以及UTF-8就是在这种条件下诞生的。

(2)GB 2312 或 GB 2312-80:是中国国家标准简体中文字符集(国标基本集)。该字符集只支持中文字符,因此通用性只局限于国内!

      GB2312包含了常用的中文字符,同时也兼容ASCII码。在这种编码规范中,ASCII码占一个字节,码值在0~127之间;中文字符占两个字节,码值在127~256之间。

(3)GBK:国标扩展编码,再GB2312的基础上支持繁体字等。兼容GB2312,支持更多的汉字。

      GBK全称《汉字内码扩展规范》(GBK即“国标”、“扩展”汉语拼音的第一个字母,英文名称:Chinese Internal Code Specification)。GBK编码,是在GB2312-80标准基础上的内码扩展规范。向下与 GB 2312 编码兼容,向上支持 ISO 10646.1国际标准,是前者向后者过渡过程中的一个承上启下的产物。

      GBK兼容GB2312编码,但比GB2312包含了更多的汉字:中文存储时,第一个字节码值在127~256之间,第二个字节码值在0~256之间。

(4)GB18030:在GBK的基础上,支持中国各个少数民族的文字

(5)UNICODE这种编码非常大,大到可以容纳世界上任何一个文字和标志。

      所以只要电脑上有 UNICODE这种编码系统,无论是全球哪种文字,只需要保存文件的时候,保存成为UNICODE编码格式的文件就可以被其他电脑正常解释。

      UNICODE在网络传输中,出现了两个标准 UTF-8 和 UTF-16,分别每次传输 8个位和 16个位。

(6)UTF-8:收录的字符是最全的,包含全球所有国家的字符,通用性最强!

      UFT8是一种国际化的编码方式,包含了世界上大部分的语种文字,也兼容ASCII码

      Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。

 

2 如何选择编码格式呢?

      编码格式的选择主要在于文本内容。

      UTF8是国际通用编码,适用范围更广,如果文本内容的英文字符较多或者注重多国用户体验的网站,UTF8是首选。

      但UTF8占用的数据库比GBK大,如果只需要显示中文字符,不考虑其他语言的情况下,可以考虑适用GBK编码,毕竟它是GB2312的超集。

 

3 各种编码之间的转换

      java编码中常遇到的编码转换问题,主要是:UTF-8、unicode与GBK编码之间的转换。

      经常需要转换的主要原因是:中文编码的问题,如果编解码不对应,经常遇到令人烦躁的乱码问题。究其原因是:在unicode系列编码和GBK系列编码中,同一个中文的字符对应的编码不同。

      UTF-8和GBK编码之间的转换必须先转换成unicode编码,然后再转换成目标编码!

 

4 代码测试编码占用字节数

/**
 * DESC: 不同编码占用字节数
 * VERSION: 0.0.1
 */
public class Encodeing {

    public static void main(String[] args) throws Exception {
        String characterEn = "A";
        String characterZhSimple = "简";
        String characterZhComplex = "簡";

        System.out.println("ASCII编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("ASCII").length);
        System.out.println();

        System.out.println("Unicode编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("Unicode").length);
        System.out.println("中文简体:" + characterZhSimple.getBytes("Unicode").length);
        System.out.println("中文繁体:" + characterZhComplex.getBytes("Unicode").length);
        System.out.println();

        System.out.println("UTF-8编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("UTF-8").length);
        System.out.println("中文简体:" + characterZhSimple.getBytes("UTF-8").length);
        System.out.println("中文繁体:" + characterZhComplex.getBytes("UTF-8").length);
        System.out.println();

        System.out.println("UTF-16编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("UTF-16").length);
        System.out.println("中文简体:" + characterZhSimple.getBytes("UTF-16").length);
        System.out.println("中文繁体:" + characterZhComplex.getBytes("UTF-16").length);
        System.out.println();

        System.out.println("GB2312编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("GB2312").length);
        System.out.println("中文简体:" + characterZhSimple.getBytes("GB2312").length);
        System.out.println();

        System.out.println("BIG5编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("BIG5").length);
        System.out.println("中文繁体:" + characterZhComplex.getBytes("BIG5").length);
        System.out.println();

        System.out.println("GBK编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("GBK").length);
        System.out.println("中文简体:" + characterZhSimple.getBytes("GBK").length);
        System.out.println("中文繁体:" + characterZhComplex.getBytes("GBK").length);
        System.out.println();

        System.out.println("GB18030编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("GB18030").length);
        System.out.println("中文简体:" + characterZhSimple.getBytes("GB18030").length);
        System.out.println("中文繁体:" + characterZhComplex.getBytes("GB18030").length);
        System.out.println();

        System.out.println("ISO-8859-1编码字节数:");
        System.out.println("英文字符:" + characterEn.getBytes("ISO-8859-1").length);
        System.out.println();
    }
}

 

5 将字符串转换成指定编码的字节数组存在的问题

      存在如下问题:

String characterZhSimple = "简";
System.out.println("字符串转换成ASCII编码的字符数组为:" + characterZhSimple.getBytes("ASCII"));

      运行结果为:63

      原因分析:只要是中文字符都变成了“63”,ASCII码为63的字符是“?”。出现这个问题的原因是因为ASCII码表不支持中文字符,因此将中文字符转换成Ascii或ISO-8859-1表对应的字节数组时,中文字符都会被转换成63(默认缺失值),导致了乱码或中文丢失!从String的getBytes()方法的源码分析可知,只要目标码表不支持的字符都会被63替换!因此我们要避免转换成字符不支持的编码字节数组!

 

      如果以上教程对您有帮助,为了不迷路,请关注一下吧~

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT_Most

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值