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

平凡也就两个字: 懒和惰;
成功也就两个字: 苦和勤;
优秀也就两个字: 你和我。
跟着我从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
    评论
目录 缩略词 正文之前 1. 目的 2. 本文内容 3. 声明 1. 字符编码相关的背景知识 1.1. 拉丁字母 1.1.1. 我们的目标 1.2. 什么是字符编码 2. 字符编码标准 2.1. 只支持基本的拉丁字符字符编码:ASCII 2.1.1. ASCII的由来 2.1.2. ASCII编码规则 2.1.2.1. ASCII字符集中的功能/控制字符 2.1.2.1.1. 什么是Function Code功能码或 Function Character功能字符 2.1.2.1.2. ASCII中的Function/Control Code功能字符的详细含义 2.1.2.1.2.1. 0 – NUL – NULl 字符/空字符 2.1.2.1.2.2. 1 – SOH – Start Of Heading 标题开始 2.1.2.1.2.3. 2 – STX,3 – ETX 2.1.2.1.2.4. 4 – EOT – End Of Transmission 传输结束 2.1.2.1.2.5. 5 – ENQ – ENQuiry 请求 2.1.2.1.2.6. 6 – ACK – ACKnowledgment 回应/响应 2.1.2.1.2.7. 7 – BEL – [audible] BELl 2.1.2.1.2.8. 8 – BS – BackSpace 退格键 2.1.2.1.2.9. 9 – HT – Horizontal Tab 水平制符 2.1.2.1.2.10. 10 – LF – Line Feed 换行 2.1.2.1.2.11. 11 – VT – Vertical Tab 垂直制符 2.1.2.1.2.12. 12 – FF – Form Feed 换页 2.1.2.1.2.13. 13 – CR – Carriage return 机器的滑动部分/底座 返回 -> 回车 2.1.2.1.2.14. 14 – SO,15 – SI 2.1.2.1.2.15. 16 – DLE – Data Link Escape 数据链路转义 2.1.2.1.2.16. 17 – DC1 – Device Control 1 / XON – Transmission on 2.1.2.1.2.17. 18 – DC2 – Device Control 2 2.1.2.1.2.18. 19 – DC3 – Device Control 3 / XOFF – Transmission off 传输中断 2.1.2.1.2.19. 20 – DC4 – Device Control 4 2.1.2.1.2.20. 21 – NAK – Negative AcKnowledgment 负面响应-> 无响应, 非正常响应 2.1.2.1.2.21. 22 – SYN – SYNchronous idle 2.1.2.1.2.22. 23 – ETB – End of Transmission Block 块传输中止 2.1.2.1.2.23. 24 – CAN – CANcel 取消 2.1.2.1.2.24. 25 – EM – End of Medium 已到介质末端,介质存储已满 2.1.2.1.2.25. 26 – SUB – SUBstitute character替补/替换 2.1.2.1.2.26. 27 – ESC – ESCape 逃离/取消 2.1.2.1.2.27. 28 – FS – File Separator 文件分隔符 2.1.2.1.2.28. 29 – GS – Group Separator分组符 2.1.2.1.2.29. 30 – RS – Record Separator记录分隔符 2.1.2.1.2.30. 31 – US – Unit Separator 单元分隔符 2.1.2.1.2.31. 32 – SP – White SPace 空格键 2.1.2.1.2.32. 127 – DEL – DELete 删除 2.1.2.1.3. 各种字符的标准的读法/叫法 2.1.3. ISO 646 2.2. 支持多种衍生拉丁字母的字符编码:EASCII和ISO 8859 2.2.1. EASCII 2.2.2. ISO 8859 2.2.2.1. ISO/IEC 8859出现的背景 2.2.2.2. ISO/IEC 8859的编码规则 2.2.2.3. ISO/IEC 8859的特点 2.2.2.4. ISO/IEC 6429 2.2.2.5. ISO 8859和ISO-8859的区别和联系 2.2.2.5.1. 原先的ISO 8859-1和我们常说的ISO 8859-1 2.3.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT_Most

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

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

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

打赏作者

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

抵扣说明:

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

余额充值