Java 编码格式认识:ASCII GB2312 GBK Unicode UTF

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/uestcyms/article/details/80247255

题记

对于计算机而言,存储的都是0和1,那么怎么使用0和1来表示这个世界呢,类似于怎么使用0和1映射到显示生活中;这时候就需要一种编码规则,将0和1组合,能够表示世界万物。

本文收益于于洋大神在知乎上绘声绘色的解答:Unicode 和 UTF-8 有何区别?

各种编码的诞生及规范

ASCII码

ASCII码,全称American Standard Code for Information Interchange,美国信息互换标准代码 ;我们知道计算机最早出现在美国,那么为了表示万物,他们(美国国家标准学会()制定了一套编码规范:使用7位或8位二进制组合来表示128或256中可能的字符;

标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符;

后128个称为扩展ASCII码,扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。

GB2312 GBK

ASCII码中可以描述英文字母、标点符号、数字;但随着计算机的普及,其他国家也使用了计算机,那么就会遇到这样的问题ASCII编码格式没办法表达其他国家的语言,拿中国为例,中华文化博大精深,常用汉字有6000多个,在计算机怎么进行表示编码呢,这时就出现了另外的编码格式:GB2312 GBK GB18030;

  • GB2312:
    《信息交换用汉字编码字符集》是由中国国家标准总局1980年发布,1981年5月1日开始实施的一套国家标准,标准号是GB 2312—1980。
    分区表示:
    GB 2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。
    01-09区为特殊符号。
    16-55区为一级汉字,按拼音排序。
    56-87区为二级汉字,按部首/笔画排序。
    10-15区及88-94区则未有编码。
    举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。
    字节结构:(由分区规则,低位字节保存位,含有94个,所以区间为0xFE-0xA1(255-94);高位字节为了与低位字节结构保持一致所以区间为0xA1-0xF7(94+87)),原来的ASCII中本来就有的也都统统重新编码成了两个字节的编码,也就是常说的”全角”,原来127以下的哪些就叫”半角”。
    每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。
    “高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上 0xA0)。 由于一级汉字从16区起始,汉字区的“高位字节”的范围是0xB0-0xF7,“低位字节”的范围是0xA1-0xFE,占用的码位是 72*94=6768。其中有5个空位是D7FA-D7FE。
    例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节) 0xA1(第二个字节)储存。区位码=区字节+位字节(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。
    编码规则:
    2字节编码,高位为0xA1-0xF7,低位为0xA1-0xFE
    汉字区域,高位为0xB0-0xF7,低位为0xA1-0xFE
    特殊符号,高位为0xA1-0xA9,低位为0xA1-0xFE
  • GBK
    是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字
    由于中国汉字太多了,包含很多古汉语等;

    当然后续又加入了几千个少数民族的字,GBK扩成了GB18030;统称为DBCS:Double Byte Charecter Set 双字节字符集。

Unicode

那么随着计算机的普及,越来越多的国家使用到它,每个国家都像中国来搞出一套编码规则,这就导致很难互通维护,为了实现大一统的,ISO组织着手解决这个问题,推出了支持各个国家的统一的编码 Universal Multiple-Octet Coded Character Set 简称 UCS,俗称 unicode。
通用字符集(Universal Character Set, UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4用4个字节编码。
在Unicode中:汉字“字”对应的数字是23383(十进制),十六进制表示为5B57。在Unicode中,我们有很多方式将数字23383表示成程序中的数据;于是为了较好的解决unicode的编码问题,UTF-8和UTF-16两种当前比较流行的编码方式就诞生了;还有UTF-32;

UTF-8

UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下:

Unicode编码(十六进制) UTF-8 字节流(二进制)
00000000-000007F 0xxxxxxx
00000080-000007FF 110xxxxx 10xxxxxx
00000800-0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000-001FFFFF 11110xxx10xxxxxx10xxxxxx10xxxxxx
00200000-03FFFFFF 111110xx10xxxxxx10xxxxxx10xxxxxx10xxxxxx
04000000-7FFFFFFF 1111110x10xxxxxx10xxxxxx10xxxxxx10xxxxxx10xxxxxx

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是6个字节。从上表可以看出,6字节模板有31个x,即可以容纳31位二进制数字。Unicode的最大码位0x7FFFFFFF也只有31位。从unicode到utf-8并不是直接的对应,而是要过一些算法和规则来转换。

扫描二维码关注公众号,回复: 5439240 查看本文章

总结

编码格式,就是二进制映射成能够表达世界万物的元素(字母、标点、符号、各国语言元素等);不同的编码格式在存储上大都不一致;

彩蛋

对于字符“c”和字符“我”在不同编码格式环境下,占有的字节数如下:

字符 US-ASCII GB2312 GBK UTF-8 UTF-16
c 1 1 1 1 4
1(但内容是?不能显示) 2 2 3 4

测试环境:Androidstudio
测试步骤:通过修改Androidstudio的编码格式,然后查看程序输出
修改androidstudio编码格式的方法:File->Settings->Editor->File Encodings:修改Global Encoding:
如下图:
AndroidStudio修改编码格式
测试程序代码如下:

public class UnicodeTest {

    public static void main(String[] args){

        System.out.println("The system encoding is : "+System.getProperty("file.encoding"));

        String ch;
        ch = "c";
        System.out.println("ch: "+ch+"\t"+"ch hex: "+Integer.toHexString((int) ch
                .charAt(0))+"\t"+"ch bytes: "+ch.getBytes().length);
        ch = "我";
        System.out.println("ch: "+ch+"\t"+"ch hex: "+Integer.toHexString((int) ch
                .charAt(0))+"\t"+"ch bytes: "+ch.getBytes().length);
    }
}

程序运行结果如图:
这里写图片描述

PS:在程序中使用System.getProperties().put(“file.encoding”, “xxx”)来进行更改环境的编码格式,发现getBytes().length是不会发生变化的;原因是String的getBytes方法,会使用Charset.defaultCharset().name()作为编码格式进行encode;而Charset.defaultCharset()在调用main方法前defaultCharset已经初始化好了,也就是使用了一开始IDE的编码格式了,程序运行后进行更改编码格式是不会反馈到getBytes方法上的。

猜你喜欢

转载自blog.csdn.net/uestcyms/article/details/80247255
今日推荐