您的位置 首页 java

Java,字符串编码,ASCII、GBK、Unicode、UTF-8、UTF-16和UTF-32

字符串编码

ASCII 和非ASCII

ASCII,American Standard Code for Information Interchange(美国信息交换标准代码),是基于拉丁字母的,主要用于显示现代英语和其他西欧语言,一个字节有8个二进制位(bit),可以表示256(2^8)种不同的状态,即256个符号,从0000000到11111111。ASCII码一共规定了128个字符的编码,如大写的字母A是65( 二进制 01000001),这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

GB2312和GBK

GB2312 或GB 2312-80是中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称 GB 0,由中国国家标准总局发布,1981年5月1日实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持 GB 2312

GBK 即汉字内码扩展规范,K为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母。英文全称Chinese Internal Code Specification。GBK 共收入21886个汉字和图形符号,包括:GB 2312 中的全部汉字、非汉字符号。BIG5 中的全部汉字。与 ISO 10646相应的国家标准 GB 13000 中的其它 CJK 汉字,以上合计 20902 个汉字。其它汉字、部首、符号,共计 984 个。GBK 向下与 GB 2312 完全兼容,向上支持 ISO 10646 国际标准,在前者向后者过渡过程中起到的承上启下的作用。

Unicode (统一码、 万国码 、单一码)

计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000至0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个,然而目前只用了少数平面。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

通用 字符集 (Universal Character Set, UCS )是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4用4个字节编码。

UTF-8

UTF-8 以字节为单位对Unicode进行编码,UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码Unicode字符。用在网页上可以统一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。

UTF-16

UTF-16 编码以16位无符号整数为单位。UTF-16是Unicode字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为 “storage format”)的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。

UTF-16是Unicode的其中一个使用方式。 UTF是Unicode TransferFormat,即把Unicode转做某种格式的意思。

它定义于ISO/IEC 10646-1的附录Q,而RFC2781也定义了相似的做法。

在Unicode基本多文种平面定义的字符(无论是拉丁字母、汉字或其他文字或符号),一律使用2字节储存。而在辅助平面定义的字符,会以代理对(surrogate pair)的形式,以两个2字节的值来储存。

UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。

UTF-32

UTF-32 编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。UTF-32 (或 UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位元,其它的Unicode transformation formats则使用不定长度编码,因为UTF-32对每个字符都使用4字节,就空间而言,是非常没有效率的。特别地,非基本多文种平面的字符在大部分文件中通常很罕见,以致于它们通常被认为不存在占用空间大小的讨论,使得UTF-32通常会是其它编码的二到四倍,虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。

操作系统支持的编码

 /**
 * 操作系统支持的编码
 */public class SupportEncodeTest {

    public static void main(String[] args) {
        Map<String,  Charset > availMap = Charset.availableCharsets();
        Set<String> keys = availMap.keySet();
        for (Iterator<String> iter = keys.iterator(); iter.hasNext(); ) {
            System.out.println(iter.next());
        }
    }

}  

Java字符串的编码

 import java.io. File Writer;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

/**
 * Java字符串的编码
 */public class EncodeTest {

    /**
     * @param args
     * @throws UnsupportedEncodingException
     */    public static void main(String[] args) throws Exception {
        // Java中字符仅以一种形式存在,那就是Unicode.
        String str = "中";
        String str2 = "\u4E2D";
        System.out.println(str.equals(str2));
        // Java中的字符是以Unicode的形式表达的,转字节数组后变成GBK编码,与操作系统一致
        System.out.println(compareEncode(str, "GBK"));
        System.out.println(compareEncode(str, "Unicode"));
        System.out.println(compareEncode(str, "UTF-16"));
        System.out.println(compareEncode(str, "UTF-16BE"));
        System.out.println(compareEncode(str, "UTF-16LE"));
        // 获取默认编码,与操作系统有关系,默认是中文GBK编码
        System.out.println("Default Charset IS: " + Charset.defaultCharset());
        System.out.println("Default Charset IS: " + System.getProperty("file.encoding"));
        FileWriter filewriter = new FileWriter("out");
        String encname = filewriter.getEncoding();
        filewriter.close();
        System.out.println("Default Charset IS: " + encname);
    }

    /**
     * @param str
     * @param encode
     * @return
     * @throws UnsupportedEncodingException
     */    private static boolean compareEncode(String str, String encode)
            throws UnsupportedEncodingException {
         byte [] bt = str.getBytes();
        byte[] bt2 = str.getBytes(encode);
        if (bt.length != bt2.length) {
            System.out.println(bt.length);
            System.out.println(bt2.length);
        } else {
            boolean result = true;
            for (int i = 0; i < bt.length; i++) {
                if (bt[i] != bt2[i]) {
                    result = false;
                }
            }
            return result;
        }
        return false;
    }

}  

Java字符串编码转换

 import java.io.UnsupportedEncodingException;

/**
 * Java字符串编码转换
 */public class ChangeCharset {

    /**
     * 7位ASCII字符,也叫作ISO646-US、Unicode字符集的基本拉丁块
     */    public static final String US_ASCII = "US-ASCII";

    /**
     * ISO 拉丁字母表 No.1,也叫作 ISO-LATIN-1
     */    public static final String ISO_8859_1 = "ISO-8859-1";

    /**
     * 8 位 UCS 转换格式
     */    public static final String UTF_8 = "UTF-8";

    /**
     * 16 位 UCS 转换格式,Big Endian(最低地址存放高位字节)字节顺序
     */    public static final String UTF_16BE = "UTF-16BE";

    /**
     * 16 位 UCS 转换格式,Little-endian(最高地址存放低位字节)字节顺序
     */    public static final String UTF_16LE = "UTF-16LE";

    /**
     * 16 位 UCS 转换格式,字节顺序由可选的字节顺序标记来标识
     */    public static final String UTF_16 = "UTF-16";

    /**
     * 中文超大字符集
     */    public static final String GBK = "GBK";

    /**
     * 将字符编码转换成US-ASCII码
     */    public String toASCII(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, US_ASCII);
    }

    /**
     * 将字符编码转换成ISO-8859-1码
     */    public String toISO_8859_1(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, ISO_8859_1);
    }

    /**
     * 将字符编码转换成UTF-8码
     */    public String toUTF_8(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, UTF_8);
    }

    /**
     * 将字符编码转换成UTF-16BE码
     */    public String toUTF_16BE(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, UTF_16BE);
    }

    /**
     * 将字符编码转换成UTF-16LE码
     */    public String toUTF_16LE(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, UTF_16LE);
    }

    /**
     * 将字符编码转换成UTF-16码
     */    public String toUTF_16(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, UTF_16);
    }

    /**
     * 将字符编码转换成GBK码
     */    public String toGBK(String str) throws UnsupportedEncodingException {
        return this.changeCharset(str, GBK);
    }

    /**
     * 字符串编码转换的实现方法
     *
     * @param str        待转换编码的字符串
     * @param newCharset 目标编码
     * @return
     * @throws UnsupportedEncodingException
     */    public String changeCharset(String str, String newCharset)
            throws UnsupportedEncodingException {
        if (str != null) {
            // 用默认字符编码解码字符串。
            byte[] bs = str.getBytes();
            // 用新的字符编码生成字符串
            return new String(bs, newCharset);
        }
        return null;
    }

    /**
     * 字符串编码转换的实现方法
     *
     * @param str        待转换编码的字符串
     * @param oldCharset 原编码
     * @param newCharset 目标编码
     * @return
     * @throws UnsupportedEncodingException
     */    public String changeCharset(String str, String oldCharset, String newCharset)
            throws UnsupportedEncodingException {
        if (str != null) {
            // 用旧的字符编码解码字符串。解码可能会出现异常。
            byte[] bs = str.getBytes(oldCharset);
            // 用新的字符编码生成字符串
            return new String(bs, newCharset);
        }
        return null;
    }

    /**
     * @param args
     * @throws UnsupportedEncodingException
     */    public static void main(String[] args) throws UnsupportedEncodingException {
        ChangeCharset changeCharset = new ChangeCharset();
        String str = "This is a 中文的 String!";
        System.out.println("str: " + str);
        String gbk = changeCharset.toGBK(str);
        System.out.println("转换成GBK码: " + gbk);
        System.out.println();
        String ascii = changeCharset.toASCII(str);
        System.out.println("转换成US-ASCII码: " + ascii);
        gbk = changeCharset.changeCharset(ascii, ChangeCharset.US_ASCII, ChangeCharset.GBK);
        System.out.println("再把ASCII码的字符串转换成GBK码: " + gbk);
        System.out.println();
        String iso88591 = changeCharset.toISO_8859_1(str);
        System.out.println("转换成ISO-8859-1码: " + iso88591);
        gbk = changeCharset.changeCharset(iso88591, ChangeCharset.ISO_8859_1, ChangeCharset.GBK);
        System.out.println("再把ISO-8859-1码的字符串转换成GBK码: " + gbk);
        System.out.println();
        String utf8 = changeCharset.toUTF_8(str);
        System.out.println("转换成UTF-8码: " + utf8);
        gbk = changeCharset.changeCharset(utf8, ChangeCharset.UTF_8, ChangeCharset.GBK);
        System.out.println("再把UTF-8码的字符串转换成GBK码: " + gbk);
        System.out.println();
        String utf16be = changeCharset.toUTF_16BE(str);
        System.out.println("转换成UTF-16BE码:" + utf16be);
        gbk = changeCharset.changeCharset(utf16be, ChangeCharset.UTF_16BE, ChangeCharset.GBK);
        System.out.println("再把UTF-16BE码的字符串转换成GBK码: " + gbk);
        System.out.println();
        String utf16le = changeCharset.toUTF_16LE(str);
        System.out.println("转换成UTF-16LE码:" + utf16le);
        gbk = changeCharset.changeCharset(utf16le, ChangeCharset.UTF_16LE, ChangeCharset.GBK);
        System.out.println("再把UTF-16LE码的字符串转换成GBK码: " + gbk);
        System.out.println();
        String utf16 = changeCharset.toUTF_16(str);
        System.out.println("转换成UTF-16码:" + utf16);
        gbk = changeCharset.changeCharset(utf16, ChangeCharset.UTF_16LE, ChangeCharset.GBK);
        System.out.println("再把UTF-16码的字符串转换成GBK码: " + gbk);
        String s = new String("中文".getBytes("UTF-8"), "UTF-8");
        System.out.println(s);
    }
}  

Java Unicode

 import org.apache.commons.lang3.StringEscapeUtils;

import java.io.UnsupportedEncodingException;

public class What21Unicode {

    /**
     * @param args
     */    public static void main(String[] args) {
        // 字符串转换为unicode码:
        String result1 = StringEscapeUtils.escapeJava("我们");
        System.out.println("result1=" + result1);
        // unicode码转为字符串:
        String result2 = StringEscapeUtils.unescapeJava("\u6211\u4EEC");
        System.out.println("result2=" + result2);
        // 字符
        String str = "我们";
        System.out.println(str);
        // unicode编码字符
        String unicode = "\u6211\u4EEC";
        System.out.println(unicode);
        // 看看该编码
        byte[] bytes = null;
        try {
            bytes = "我们".getBytes("UTF-16BE");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < bytes.length; i++) {
            String cStr = Integer.toHexString(bytes[i]);
            if (cStr.length() >= 8) {
                cStr = cStr.substring(6, 8);
            }
            System.out.print(cStr + " ");
        }
        System.out.println();
    }

}
  

文章来源:智云一二三科技

文章标题:Java,字符串编码,ASCII、GBK、Unicode、UTF-8、UTF-16和UTF-32

文章地址:https://www.zhihuclub.com/181645.shtml

关于作者: 智云科技

热门文章

网站地图