字符编码

2020-04-07  本文已影响0人  userheng

Unicode字符集

在unicode出现之前,有很多编码标准,如:

编码标准
英语语系 ASCII (7个bit表示一个字符)
西欧 ISO 8859-1 (8个bit表示一个字符)
中国 GBK

多种编码标准产生了以下问题:

  1. 某个字符可能不在某个编码标准中。
  2. 某个字符在不同的编码标准中,其编码值不同。

Unicode字符集中包含了全球所有的通用字符,每个字符都有一个编码值,但并没有指明该字符如何在计算机中存储。

Unicode主要使不同编码标准之间的相互转换成为可能。

Unicode字符集的实现

几个专业术语的介绍:

UTF-16

UTF-16编码是Unicode字符集其中的一种实现,字符Unicode值到UTF-16编码值的转换示例如下:

字符 Unicode值(16进制) UTF-16编码值(字节之间的值以逗号分隔)
A 0x0041 0,65
0x8861 -120,97

Java char类型与UTF-16

Java语言采用的是UTF-16编码标准,一个char占两个字节,恰好与UTF-16的一个码点单元所占大小相同。

一个码点单元16位,其值范围0~65535。可以容纳65535个字符,但后来又扩充了大量的新增字符(如中文、韩文、日文的表意字符)。一个char自然就无法表示这些字符了,至少需要一对char来表示。

如字符:"𝕆",其码点值(Unicode编码值)为:\u1d546。需要\ud835和\udd46两个码点单元来表示。

        /*
         * 两个char才能表示该字符,故只能用字符串引用。即 new String(new char[] {'\ud835','\udd46'})
         */
        String cc = "𝕆";

        System.out.println("cc的码点单元:" + cc.length() + "个");// 2

        // cc是一个字符,码点值(Unicode编码值)自然是1
        System.out.println("cc的码点值有" + cc.codePointCount(0, cc.length()) + "个");// 1

        int codePonitValue = cc.codePointAt(0);
        System.out.printf("cc的码点值%d, 十六进制为%x", codePonitValue, codePonitValue);// 120134 1d546
        
        
        System.out.println("");
        byte[] bytes = cc.getBytes("UTF-16");
        for (byte b : bytes) {
            System.out.print(b+",");//-2,-1,-40,53,-35,70,  
        }
        System.out.println("");
        
        //-2,-1应该是UTF-16的前缀标志
        System.out.println(new String(new byte[] {-40,53,-35,70}, "UTF-16"));//𝕆

程序输出:

cc的码点单元:2个
cc的码点值有1个
cc的码点值120134, 十六进制为1d546
-2,-1,-40,53,-35,70,
𝕆
上一篇下一篇

猜你喜欢

热点阅读