相信大家很多人跟我一样,对于编码一直感觉云山雾罩,说知道吧?就知道gb2312是中文编码,一看见乱码,就知道是编码出了问题,但是是哪儿出问题,为什么出问题,除了蒙,还是蒙。尤其是弄好了之后,有人问:为什么呢。自己也不知道,就说:反正就是这样的,用什么编码就用什么解码。为什么,鬼知道。
其实问题还是理解了之后,才能真正的明白为什么会这样,而且编码这个问题,也不是那么深奥,在网上搜索了一些资料,算是一直以来对编码问题的一个解决吧,最让人明白的资料有两个,第一个:
http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html
这个关于编码,我认为是最清楚的了,刚开始看完之后,觉得自己是真明白了,gb2312只是一个字符集,而unicode是所有能用到的字符的一个总集,utf-8是一种编码。它的字符集就是unicode。而且unicode是全人类达成共识的巨大的字符集,包括了gb2312字符集。
有了这个“底气”之后,就开始了自己的探索了:
1、用记事本一个写一个xml,如下:<?xml version="1.0" encoding="gb2312"?>
<root>
<person>hi,大 美女你好</person>
</root> 将这个记事本保存为utf-8格式,然后打开,乱码,想也没想,感觉就是:用utf-8编码的文件,用gb2312的去解码,有的utf-8字符gb2312都没有,肯定会出问题了(这个理解是错误的!!!)
2、用记事本一个写一个xml,如下:<?xml version="1.0" encoding="utf-8"?>
<root>
<person>hi,大 美女你好</person>
</root> 将这个记事本保存为ansi格式(在简体中文的操作系统下,就是gb2312编码),然后打开,乱码???为什么呢?unicode编码不是包含了gb2312的字符集吗?按说应该能解析啊???(延续了第一个的想法,仅仅以字符集的大小去判断,还是错误的)
没办法,只能继续网上找答案了,于是第二个资料出现了。
http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/f656ec85-2cd0-4d6a-a207-fe30523cc5a4/
对于这个问题是这样说的:“UTF-8中包含所有 gb2312 中的字符的定义 但是 每个字符的编号却不是完全对应 的 所以就会出现页面的中文字不能对应 的情况”
答案详见4楼Raymond Tang 版主的答案。
这样的话,就可以解释了为什么utf-8解析不了gb2312中的字符了。
但是,我觉得这个答案还是有问题,像Raymond Tang版主所说,“每个字符的编号却不是完全对应 的”,他的意思,应该是gb2312中的编码和utf-8的编码编号是不一样的,所以不能解析出正确的字符。而如果仅仅是编码不一样,那至少也不会变化太大,应该是差不多还是个汉字吧?为啥成乱码呢?
于是,我又仔细看了看第一篇文章,感觉发现了问题的所在:“GB2312以及GBK字符集,限定了使用最多2个字节来编码所有字符,并且规定了字节序。这样的编码系统通常用简单的查表,也就是通过代码页就可以直接将字符映射为存储设备上的字节流了。”,而:“虽然每个字符在Unicode字符集中都能找到唯一确定的编号(字符码,又称Unicode码),但是决定最终字节流的却是具体的字符编码”,这时,就由utf-8来决定了。简单的来说,就是字符流被打乱了,utf-8是变长编码的,它不能按照gb2312那样解析字节流。所以出现了乱码。
所以,终归到底,unicode是包含了gb2312中的字符集,但是每种编码解码方式不一样,也就是说,utf-8编码是一种规则,他自己编码的字节流,需要用自己的规则去解码,如果不一致,就会出现乱码情况。这就是根源所在。 期间还发现了个挺有趣的事情:当新建文本文档只输入“联通”2字保存再打开时将是乱码。
详见:http://baike.baidu.com/view/1273097.htm 这个帖子是我自己的一个总结,以备啥时候忘了能提醒自己,同时希望能对像我一样不明白的一些童鞋有些帮助,让那些早就深刻理解这些东西的人来说见笑了
如果我理解的还是有什么偏差,希望大家能够指正。谢谢。
其实问题还是理解了之后,才能真正的明白为什么会这样,而且编码这个问题,也不是那么深奥,在网上搜索了一些资料,算是一直以来对编码问题的一个解决吧,最让人明白的资料有两个,第一个:
http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html
这个关于编码,我认为是最清楚的了,刚开始看完之后,觉得自己是真明白了,gb2312只是一个字符集,而unicode是所有能用到的字符的一个总集,utf-8是一种编码。它的字符集就是unicode。而且unicode是全人类达成共识的巨大的字符集,包括了gb2312字符集。
有了这个“底气”之后,就开始了自己的探索了:
1、用记事本一个写一个xml,如下:<?xml version="1.0" encoding="gb2312"?>
<root>
<person>hi,大 美女你好</person>
</root> 将这个记事本保存为utf-8格式,然后打开,乱码,想也没想,感觉就是:用utf-8编码的文件,用gb2312的去解码,有的utf-8字符gb2312都没有,肯定会出问题了(这个理解是错误的!!!)
2、用记事本一个写一个xml,如下:<?xml version="1.0" encoding="utf-8"?>
<root>
<person>hi,大 美女你好</person>
</root> 将这个记事本保存为ansi格式(在简体中文的操作系统下,就是gb2312编码),然后打开,乱码???为什么呢?unicode编码不是包含了gb2312的字符集吗?按说应该能解析啊???(延续了第一个的想法,仅仅以字符集的大小去判断,还是错误的)
没办法,只能继续网上找答案了,于是第二个资料出现了。
http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/f656ec85-2cd0-4d6a-a207-fe30523cc5a4/
对于这个问题是这样说的:“UTF-8中包含所有 gb2312 中的字符的定义 但是 每个字符的编号却不是完全对应 的 所以就会出现页面的中文字不能对应 的情况”
答案详见4楼Raymond Tang 版主的答案。
这样的话,就可以解释了为什么utf-8解析不了gb2312中的字符了。
但是,我觉得这个答案还是有问题,像Raymond Tang版主所说,“每个字符的编号却不是完全对应 的”,他的意思,应该是gb2312中的编码和utf-8的编码编号是不一样的,所以不能解析出正确的字符。而如果仅仅是编码不一样,那至少也不会变化太大,应该是差不多还是个汉字吧?为啥成乱码呢?
于是,我又仔细看了看第一篇文章,感觉发现了问题的所在:“GB2312以及GBK字符集,限定了使用最多2个字节来编码所有字符,并且规定了字节序。这样的编码系统通常用简单的查表,也就是通过代码页就可以直接将字符映射为存储设备上的字节流了。”,而:“虽然每个字符在Unicode字符集中都能找到唯一确定的编号(字符码,又称Unicode码),但是决定最终字节流的却是具体的字符编码”,这时,就由utf-8来决定了。简单的来说,就是字符流被打乱了,utf-8是变长编码的,它不能按照gb2312那样解析字节流。所以出现了乱码。
所以,终归到底,unicode是包含了gb2312中的字符集,但是每种编码解码方式不一样,也就是说,utf-8编码是一种规则,他自己编码的字节流,需要用自己的规则去解码,如果不一致,就会出现乱码情况。这就是根源所在。 期间还发现了个挺有趣的事情:当新建文本文档只输入“联通”2字保存再打开时将是乱码。
详见:http://baike.baidu.com/view/1273097.htm 这个帖子是我自己的一个总结,以备啥时候忘了能提醒自己,同时希望能对像我一样不明白的一些童鞋有些帮助,让那些早就深刻理解这些东西的人来说见笑了
如果我理解的还是有什么偏差,希望大家能够指正。谢谢。
解决方案 »
- 错误:检索 COM 类工厂中 CLSID 为 {} 的组件时失败,原因是出现以下错误: 8000401a
- 我写了个返回查询的字段值函数 但是不行请大家多指教!谢谢
- c#操作數據庫到底用什麼命令好
- 关于ClickOnce安装部署浅薄的问题!
- 有关Asp.Net中大文件上传的问题!
- 排程數據庫設計
- 关于删除DataGrid中行的问题!
- 怎样获得控件的属性
- 请问各位高手,C#中能不能实现 比如在下拉框中打入字后下拉框寻找下拉框中的内容自动填充显示 加分
- 如何通过程序控制小键盘Num Lock键的开和关?
- Dictionary 和 Hashtable 的效率问题啊
- 通过key访问的情况下,Dictionary ,HashTable,SortedList,SortedDictionary哪个更快?
然后把所有的中文字符写入另一个JS文件,所有文件都调用这个JS文件内容来输出中文信息。一般还不会使用gzip压缩,gzip压缩会降低浏览器的解吸效果。除非这个JS程序员对编码的意识并不清楚。
GB2312编码,这样的编码写的文件,短字符只占一字节
Unicode或者UTF-8编码,在这样的编码下,所有的短字符(a-zA-Z等)都会占用2字节。
请教下 这是为什么? 我的理解怎么相反?
第二种编码模式是多字节字符集(multi-byte character set or MBCS)。一个MBCS编码包含一些一个字节长的字符,而另一些字符大于一个字节的长度。用在Windows里的MBCS包含两种字符类型,单字节字符(single-byte characters)和双字节字符(double-byte characters)。由于Windows里使用的多字节字符绝大部分是两个字节长,所以MBCS常被用DBCS代替。
在DBCS编码模式中,一些特定的值被保留用来表明他们是双字节字符的一部分。例如,在Shift-JIS编码中(一个常用的日文编码模式),0x81-0x9f之间和 0xe0-oxfc之间的值表示"这是一个双字节字符,下一个子节是这个字符的一部分。"这样的值被称作"leading bytes",他们都大于0x7f。跟随在一个leading byte子节后面的字节被称作"trail byte"。在DBCS中,trail byte可以是任意非0值。像SBCS一样,DBCS字符串的结束标志也是一个单字节表示的0。
第三种编码模式是Unicode。Unicode是一种所有的字符都使用两个字节编码的编码模式。Unicode字符有时也被称作宽字符,因为它比单子节字符宽(使用了更多的存储空间)。注意,Unicode不能被看作MBCS。MBCS的独特之处在于它的字符使用不同长度的字节编码。Unicode 字符串使用两个字节表示的0作为它的结束标志。
单字节字符包含拉丁文字母表,accented characters及ASCII标准和DOS操作系统定义的图形字符。双字节字符被用来表示东亚及中东的语言。Unicode被用在COM及Windows NT操作系统内部。
你一定已经很熟悉单字节字符。当你使用char时,你处理的是单字节字符。双字节字符也用char类型来进行操作(这是我们将会看到的关于双子节字符的很多奇怪的地方之一)。Unicode字符用wchar_t来表示。Unicode字符和字符串常量用前缀L来表示。例如:wchar_t wch = L''1''; // 2 bytes, 0x0031
wchar_t* wsz = L"Hello"; // 12 bytes, 6 wide characters字符在内存中是怎样存储的 单字节字符串:每个字符占一个字节按顺序依次存储,最后以单字节表示的0结束。例如。"Bob"的存贮形式如下:
42 6F 62 00
B o b BOSUnicode的存储形式,L"Bob"
42 00 6F 00 62 00 00 00
B o b BOS使用两个字节表示的0来做结束标志。 一眼看上去,DBCS 字符串很像 SBCS 字符串,但是我们一会儿将看到 DBCS 字符串的微妙之处,它使得使用字符串操作函数和永字符指针遍历一个字符串时会产生预料之外的结果。字符串"" ("nihongo")在内存中的存储形式如下(LB和TB分别用来表示 leading byte 和 trail byte)
93 FA 96 7B 8C EA 00
LB TB LB TB LB TB EOS
EOS值得注意的是,"ni"的值不能被解释成WORD型值0xfa93,而应该看作两个值93和fa以这种顺序被作为"ni"的编码。
你使用一个记事本存储一些UTF-8的短字符,然后查看记事本的属性就知道到底占几个字节了,
不过记事本存储的UTF-8会额外增加两字节做为标识,比如存储“00000”的UTF-8文本,文件会占12字节
utf16-utf8 转换规律 http://www.cnblogs.com/baiefjg/archive/2009/03/20/1417995.html
=======================================
其实我这句话的意思就是,我对gb2312了解的很少,仅仅知道他是中文编码而已,不知道有关它的更深入的东西。仅此而已....
ANSI, UNICODE,UNICODE Big Endian, UTF-8是编码方式
GB2312, GBK, BIG5等是字符集
二者不能混谈
人可以分男人,女人
也可以分老人,小孩,等
但不能分男人,老人这样分
汉字“我”在ANSI下16进制为:CE D2
汉字“我”在UTF-8下16进制为:EF BB BF E6 88 91 为什么会偏差这么多。晕了。
----------
不太准确...早期简体中文系统里默认是GB2312,现在的系统默认是GBK...