Unicode编码

转载自: http://blog.163.com/lyq_163_2009/blog/static/1340826962011687851151/

 

 

Unicode编码简介

 

Unicode(统一码、万国码、单一码、标准万国码)是计算机科学领域里的一项业界标准,用以统一地体现和处理世界上大部分的文字系统,并为其编码。

Unicode 依照通用字符集(Universal Character Set)的标准来发展,同时也以书本的形式对外发表。Unicode至今仍在不断扩增,每个新版本都加入更多新的字符。目前最新的Unicode第六版, 除了已纳入超过十万个字符(Unicode的第十万个字符在2005年获采纳,且认可成为标准之一),还包含可用作视觉参考的代码图表、编码方法、标准的 字符编码,以及记录了如大小写字母等字符特性的列表这些数据。

链接: Unicode编码    

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

Unicode编码方式

 

Unicode 的编码方式与ISO10646的通用字符集(Universal Character Set, S)概念相对应,目前实际应用的Unicode版本对应于 S-2,使用16位的编码空间。也就是每个字符占用2个字节。这样理论上一共最 多可以表示2的16次方,即65536个字符。基本满足各种语言的使用。实际上当前版本的Unicode尚未填充满这16位编码,保留了大量空间作为特殊 使用或将来扩展。

链接:  中文说明        官方说明        各种字符集的对应关系        Unicode编码表          

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

Unicode实现方式

 

Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的,但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)。

Unicode 的编码方式与ISO10646的通用字符集(Universal Character Set, S)概念相对应,使用16位的编码空间。它固定使用16 bits(两个字节)来表示一个字符,也就是每个字符占用2个字节,共可以表示65536个字符,基本满足各种语言的使用。

标准的Unicode称为UTF-16。后来为了双字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8。

UTF8是一种Unicode编码,即它的编码的字符集和Unicode是一致的,但编码的方式不一样。

字符集: 一组抽象字符的集合就是字符集(Charset)。

编码:计算机要处理各种字符,就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding)。 

Unicode字符集有多种编码形式。

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

UTF-16编码

 

UTF-16由RFC2781规定,它使用两个字节来表示一个代码点。UTF-16是完全对应于UCS-2的,即把UCS-2规定的代码点通过Big Endian或Little Endian方式直接保存下来。UTF-16BE和UTF-16LE不难理解,而UTF-16就需要通过在文件开头的字符来表明文件是Big Endian还是Little Endian。Big Endian为:FE FF,Little Endian为:FF FE。

代码点(Code Point)就是指Unicode中为字符分配的编号,一个字符只占一个代码点,例如我们说到字符“汉”,它的代码点是U+6C49。代码单元(Code Unit)则是针对编码方法而言,它指的是编码方法中对一个字符编码以后所占的最小存储单元。代码单元就是代码点的集合,在每种编码形式中,代码点被映射到一个或多个代码单元。UTF-16中的代码单元由 16 位组成。 

编码               字符         表示方式                         备注

UTF-16BE     ABC         0  41 0  42 0  43                     

UTF-16LE     ABC         41 0  42 0  43 0                       

UTF-16         ABC         fe ff 0  41 0  42 0 43        UTF-16  Big Endian

Unicode        ABC         ff fe 41 0  42 0  43  0       UTF-16 Little Endian

所以,Unicode编码就是 UTF-16 Little Endian,UTF-16编码就是UTF-16 Big Endian。

 

package com.nice.util;

 

public class UnicodeUtil {

 

    public static void printByte(byte[] bt){

        for(int i=0; i<bt.length; i++){

            System.out.print(Integer.toHexString(bt[i]) + " ");

        }

        System.out.println();

    }

 

    /**

     * @param args

     */

    public static void main(String[] args)throws Exception {

        String content = "ABC";

        printByte(content.getBytes("Unicode"));

        printByte(content.getBytes("UTF-16"));

        printByte(content.getBytes("UTF-16BE"));

        printByte(content.getBytes("UTF-16LE"));

    }

 

}

 

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

增补字符

 

Unicode码空间为U+0000到U+10FFFF,一共1114112个码位,其中只有1112064个码位是合法的,有2048个码位不合法,但并不是说现在的Unicode就有这么多个字符了,实际上其中很多码位还是空闲的,到Unicode 4.0 规范为止,只有96382个码位被分配了字符。其中U+0000 到U+FFFF的部分被称为基本多语言面(Basic Multilingual Plane,BMP)。

U+10000及以上的字符称为补充字符。在Java中(Java1.5之后),补充字符使用两个char型变量来表示,这两个char型变量就组成了所谓的surrogate pair(在底层实际上是使用一个int进行表示的)。第一个char型变量的范围称为 :“高代理部分”(high-surrogates range,从uD800到uDBFF,共1024个码位), 第二个char型变量的范围称为:“低代理部分”(low-surrogates range,从uDC00到uDFFF,共1024个码位),这样使用surrogate pair可以表示的字符数一共是1048576个,加上BMP的65536个码位,去掉2048个非法的码位,正好是1112064个码位。

增补字符是Unicode标准中代码点超出 U+FFFF 的字符。

通过看它的第一个char是不是在高代理范围内,第二个char是不是在低代理范围内,就能确认是增补字符。这也意味着,高代理和低代理所占的共2048个码位(从0xD800到0xDFFF)是不能分配给其他字符的。

 

package com.nice.util;

 

public class CharUtil {

 

    /**

     * @param args

     */

    p lic static void main(String[] args) {

        // 确定表示指定字符(Unicode代码点)所需的 char 值的数量

        System.out.println(Character.charCount(0X10000));

        // 确定给出的 char 值是否为一个高代理项代码单元(也称为前导代理项代码单元)

        System.out.println(Character.isHighSurrogate((char)0Xd87e));

        // 确定给定 char 值是否一个低代理项代码单元(也称为尾部代理项代码单元)

        System.out.println(Character.isLowSurrogate((char)0Xdc1a));

        String s=String.valueOf(Character.toChars(0X2F81A));

        char[]chars=s.toCharArray();

        for(char c:chars){

            System.out.format("%x",(short)c);

        }

        // d87edc1a

        // 这个字符变成了两个char型变量,其中0xd87e就是高代理部分的值,0xdc1a就是低代理的值。

    }

 

}

 

 

执行输出内容:

2

true

true

d87edc1a

 

Java中1个char类型变量可以存储一个中文字符。对于增补字符,需要2个char来表示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值