美文网首页
java编码知识

java编码知识

作者: 锅锅与倩倩 | 来源:发表于2018-03-22 11:10 被阅读0次

    ASCII

    ASCII 全称American Standard Code Information Interchange 美国信息互换标准代码,共有128位。

    ISO8859-1

    128位肯定是不够的,所以ISO又在ASCII 的基础上拓展了大多数西欧字符。

    GB2312

    每个国家都有自己的文字,所以GB2312应运而生。GB2312兼容ASCII ,固定采用2个字节,收录了6763个汉字,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符,而原来在127号以下的那些就叫”半角”字符了。

    GBK

    GBK 即汉字内码扩展规范,K 为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母,完全兼容GB2312,同样固定采用双字节。增加了繁体字等。

    GB18030

    GB18030的编码采用单字节、双字节和4字节方案,其中单字节、双字节完全兼容GBK,增加了更多的文字。

    Unicode

    Unicode是由ISO组织设计,可以容纳全世界所有语言文字的编码方案,简称UCS。Unicode最多有4个字节,但大部分都是2个字节,对应的是UCS-2和UCS-4,主流的文字都在Unicode的第一片区(plane 0),也叫asic Multilingual Plane, 即BMP。但Unicode只是规定如何编码,并没有规定如何传输、保存这个编码。例如“汉”字的Unicode编码是6C49

    Unicode的问题

    Unicode的长度是固定的,但如果是纯英文的内容,会造成传输的巨大浪费。

    UTF

    UTF全称UCS Transfer Format,顾名思义UTF-32表示4个字节表示一个字符,UTF-16采用了2字节或4字节的方式来完成编码,而UTF-8是一种变长的编码方式,它使用1-4个字节表示一个字符。

    BOM

    UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

    Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

    在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

    这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

    UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

    几种编码方式的比较

    UTF-16的编码效率较高,从字符到字节的转换更简单,如java的内存编码就是用UTF-16,但它不适合在网络之间传输,因为网络传输容易损失字节流,而UTF-16容错性低,可能导致所有后续字符全部错乱。而且UTF-8在纯英文下更短,且UTF-8兼容ascii。UTF-16有字节序要求,而UTF-8没有。最新Unicod版本中字符数量已经超过了UTF-16的上线,UTF-8就没有这个问题。

    java中的char

    首先要分清内码(internal encoding)和外码(external encoding)。
    内码 :某种语言运行时,其char和string在内存中的编码方式。
    外码 :除了内码,皆是外码,比如源代码编译产生的目标代码文件。

    char类型用于表示单个字符,使用UTF-16进行编码,早期,UTF-16采用固定长度2字节的方式编码,两个字节可以表示65536种符号,足以表示当时unicode中所有字符。但是随着unicode中字符的增加,2个字节无法表示所有的字符,UTF-16采用了2字节或4字节的方式来完成编码。Java为应对这种情况,考虑到向前兼容的要求,Java用一对char来表示那些需要4字节的字符。所以,java中的char是占用两个字节,只不过有些字符需要两个char来表示。

    char[] c = Character.toChars(Integer.parseInt("1D306", 16));
    char c1 = 99;
    char c2 = '\u6c49';
    System.out.println(c);
    System.out.println(c1);
    System.out.println(c2);
    

    相关文章

      网友评论

          本文标题:java编码知识

          本文链接:https://www.haomeiwen.com/subject/ffmoqftx.html