zoukankan      html  css  js  c++  java
  • 编码和乱码

      之前总是对乱码问题手足无措,遇到了就百度,解决后也没深究,就不管了,这次又遇到了,怎么说也要把它搞清楚,透彻。

      我理解的编码在生活场景中的反映就像是,你站在超市储物箱前面,用手上的要是打开对应位置的箱子,取出其中的物品,编码也是这样的,你手上拿着这个字符的01数字串,根据他的编码表找到他对应的文字,取出来展示就是了。举个栗子:e4b8ad查询utf-8编码表可知是“中”这个字。那么乱码是怎么产生的呢?很简单,你拿着那串钥匙跑到隔壁超市取东西,嘿,很巧,那个钥匙可以开那个锁,你打开箱子发现“这不是我的东西啊,什么鬼?”编码也是一样的你拿着e4b8ad去查gbk(gbk是固定2个字节)发现e4b8是“涓”,肯定也是同样的纳闷“这不是我想要的字啊!”。

      以上就是我对编码和乱码的理解,下面来普及下编码的基础知识。

       1.ASCII码

      这是美国在19世纪60年代的时候为了建立英文字符和二进制的关系时制定的编码规范,它能表示128个字符,其中包括英文字符、阿拉伯数字、西文字符以及32个控制字符。它用一个字节来表示具体的字符,但它只用后7位来表示字符(2^7=128),最前面的一位统一规定为0。

      2.扩展的ASCII码

      原本的ASCII码对于英文语言的国家是够用了,但是欧洲国家的一些语言会有拼音,这时7个字节就不够用了。因此一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使 用的编码体系,可以表示最多256个符号。但这时问题也出现了:不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码 中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0—127表示的符号是一样的,不一样的只是128—255的这一段。这个问题就直接促使了Unicode编码的产生。

      3.Unicode

      为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。
    Unicode字符集可以简写为UCS(Unicode Character Set)。早期的unicodeUnicode标准有UCS-2、UCS-4的说法。UCS-2用两个字节编码,UCS-4用4个字节编码。
    在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS,Double Byte Character System),因此,这种方式存放的字符也被称作宽字节字符。比如,字符串 "中文123" 在 Windows 2000 下,内存中实际存放的是 5 个序号,一共10个字节。
    Unicode字符集包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

      4.UTF-8

      UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码(定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。

      基本的编码和乱码的知识也都了解了,那么我又有个小问题,从认识java开始就一直灌输着java是用Unicode编码的,那么这里的编码到底是什么意思呢?我在eclipse的window-->preferences-->general-->workspace设置Text file encoding为utf-8是设置的什么呢?和jsp里面设置的charset=UTF-8有什么联系吗?

      这里对Unicode进行补充,Unicode字符集只是定义了字符的集合和唯一编号,Unicode编码,则是对UTF-8、UCS-2/UTF-16等具体编码方案的统称而已,并不是具体的编码方案。所以当需要用到字符编码的时候,你可以写gb2312,codepage936,utf-8,utf-16,但请不要写unicode。UTF-8是Unicode的实现方式之一。

      jsp页面中的这个字符设置是做给浏览器解析的。而我们用记事本打开并另存为的那个编码是给编辑文件看的,就是说当你用GBK保存时,其他的编辑文件应也以GBK的编码去查看编辑,否则看不到正确的中文显示。而在Eclipse中的Text File Encoding就是查看时的编码(好像它不能真正修改文件的编码格式),如果本来是GBK或UTF-8的编码,在Eclipse中式用UTF-8或GBK去查看,肯定显示乱码。

      下面让我们用代码来证明以上观点

    public static void main(String[] args) throws IOException {
            System.out.println(Charset.defaultCharset());
            String a = "中文";
            byte[] aa = a.getBytes("utf-8");
            for(byte b : aa){
                System.out.println(Integer.toHexString(b & 0xFF));//将byte转换成无符16进制整数
            }
            System.out.println(new String(aa, "gbk"));
        }
    View Code

    结果输出为:

    UTF-8
    e4
    b8
    ad
    e6
    96
    87
    涓�枃
    e4b8为ade6为�9687为枃

    这里差不多对编码和乱码已经解释的差不多了。以上代码其实还有个小问题,下篇再写。

      

  • 相关阅读:
    mysql 和navicat for mysql 安装教程
    Linux 下配置php开发环境
    RecyclerView的使用(四)
    RecyclerView的使用(三)
    RecyclerView的使用(二)
    RecyclerView的使用(一)
    适配器(一)
    ListView简介
    Android ListView 详解
    android SwipeRefreshLayout google官方下拉刷新控件
  • 原文地址:https://www.cnblogs.com/vincentren/p/5939197.html
Copyright © 2011-2022 走看看