java基础--字符转换Unicode

本文详细介绍了字符编码的发展历程,包括ASCII码、扩展ASCII码、GB-2312、MBCS、Unicode及UTF-8编码方式,并通过实例展示了不同编码方式间的转换过程。
  计算机发明后,为了在计算机中表示字符,人们制定了一种编码,叫ASCII码。ASCII码由一个字节中的7位(bit)表示,范围是0x00 - 0x7F 共128个字符。
后来他们突然发现,如果需要按照表格方式打印这些字符的时候,缺少了“制表符”。于是又扩展了ASCII的定义,使用一个字节的全部8位(bit)来表示字符了,这就叫扩展ASCII码。范围是0x00 - 0xFF 共256个字符。
中国人利用连续2个扩展ASCII码的扩展区域(0xA0以后)来表示一个汉字,该方法的标准叫GB-2312。后来,日文、韩文、阿拉伯文、台湾繁体(BIG-5)......都使用类似的方法扩展了本地字符集的定义,现在统一称为 MBCS 字符集(多字节字符集)。这个方法是有缺陷的,因为各个国家地区定义的字符集有交集,因此使用GB-2312的软件,就不能在BIG-5的环境下运行(显示乱码),反之亦然。
为了把全世界人民所有的所有的文字符号都统一进行编码,于是制定了UNICODE标准字符集。UNICODE 使用2个字节表示一个字符(unsigned shor int、WCHAR、_wchar_t、OLECHAR)。
这下终于好啦,全世界任何一个地区的软件,可以不用修改地就能在另一个地区运行了。虽然我用 IE 浏览日本网站,显示出我不认识的日文文字,但至少不会是乱码了。UNICODE 的范围是 0x0000 - 0xFFFF 共6万多个字符,
其中光汉字就占用了4万多个
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 
如表: 
1字节 0xxxxxxx 
2字节 110xxxxx 10xxxxxx 
3字节 1110xxxx 10xxxxxx 10xxxxxx 
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
因此UTF-8中可以用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去那些控制位(每字节开头的10等),这些x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。 
实际将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数。 
因此那些基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一个字节的UTF-8编码(7个二进制位)便可以表示。 

对于上面的问题,代码中给出的两个字节是 
十六进制:C0 B1 
二进制:11000000 10110001 
对比两个字节编码的表示方式: 
110xxxxx 10xxxxxx 
提取出对应的UNICODE编码: 
00000 110001 
可以看出此编码并非“标准”的UTF-8编码,因为其第一个字节的“有效编码”全为0,去除高位0后的编码仅有6位。由前面所述,此字符仅用一个字节的UTF-8编码表示就够了。 
JAVA在把字符还原为UTF-8编码时,是按照“标准”的方式处理的,因此我们得到的是仅有1个字节的编码。 
package com.bdqn;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class  JavaTounicode {

    /**
     * @param args
     * @throws UnsupportedEncodingException 
     */
    public static void main(String[] args)  {
            String cn = "def";
            
            System.out.println(cnToUnicode(cn));
            // 字符串 : \u5f00\u59cb\u4efb\u52a1 ,由于 \ 在java里是转义字符,要写出下面这种形式
            String unicode = "\\u6000\\u5ff5\\u5916\\u5a46\\u5c4b\\u540e\\u7684\\u67da\\u5b50\\u6811";
            System.out.println(unicodeToCn(unicode));
        }
         
        private static String unicodeToCn(String unicode) {
            /** 以 \ u 分割,因为java注释也能识别unicode,因此中间加了一个空格*/
            String[] strs = unicode.split("\\\\u");
            String returnStr = "";
            // 由于unicode字符串以 \ u 开头,因此分割出的第一个字符是""。
            for (int i = 1; i < strs.length; i++) {
              returnStr += (char) Integer.valueOf(strs[i], 16).intValue();
            }
            return returnStr;
        }
         
        private static String cnToUnicode(String cn) {
            char[] chars = cn.toCharArray();
            String returnStr = "";
            for (int i = 0; i < chars.length; i++) {
              returnStr += "\\u" + Integer.toString(chars[i], 16);
            }
            return returnStr;
        }
}
javaTounicode
package com.zwj.thread;
import java.io.UnsupportedEncodingException;

public class Test {

    /**
     * @param args
     * @throws UnsupportedEncodingException 
     */
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str ="中国";
        byte[] data =str.getBytes();
        //字节数不完整
        System.out.println(new String(data,0,3));
        test1();
    }
    /**
     * 编码与解码字符集必须相同,否则乱码
     * @throws UnsupportedEncodingException 
     */
    public static void test1() throws UnsupportedEncodingException{
                //解码 byte -->char  
                String str ="中国"; //gbk 
                //编码 char -->byte
                byte[] data =str.getBytes();
                //编码与解码字符集同一  中国
                System.out.println(new String(data));
                
                
                data =str.getBytes("utf-8"); //设定编码字符集
                //不统一出现乱码  涓浗
                System.out.println(new String(data,"gbk"));
                
                //编码
                byte[] data2 = "中国".getBytes("utf-8");
                //解码   中国
                str=new String(data2,"utf-8");
                System.out.println(str);
    }

}
Test 编码和解码要一直

 

出现的乱码形式的含义:

??????    --->    代表字符编码不匹配造成

å¸é¾       --->    代表没有该编码方式

转载于:https://www.cnblogs.com/ou-pc/p/7662039.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值