java基础--字符转换Unicode

  计算机发明后,为了在计算机中表示字符,人们制定了一种编码,叫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 编码和解码要一直
复制代码

 

出现的乱码形式的含义:

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

师龙       --->    代表没有该编码方式

posted @   周无极  阅读(2335)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示