首页 > 代码库 > Unicode 转~!!!!!

Unicode 转~!!!!!

Unicode编码  

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来表示。

Unicode 转~!!!!!