编码问题

原创 2007年09月30日 17:06:00

字符串编码(charset, encoding/decoding)问题原理

编码问题很重要,关于编码问题的文章也很多。我本来没有兴趣重复这个主题。
一个朋友问我有没有比较好的编码介绍文章。我记得以前看过几篇很不错的,但是当时搜索到的时候,就比较费劲,一时想不起来。于是,我就说,我攒一篇好了。

---------------------------------------

编码无处不在。Database, file, editor, IDE, compiler, browser。
代码(比如java, jsp, asp, php, python, ruby etc)里面的字符串比较麻烦,涉及到editor, compiler, interpreter等等。
所以,我的做法是,从来不在代码里面直接写字符串资源,尤其是双字节编码的字符串资源。
都是把字符串资源分离到一个单独的资源文件里面。这样,只需要照管这个文件的编码就够了。
需要注意的一点是,文件里面、数据库里面、网络传输需要的数据,都是byte[]。
以下的讨论,不涉及代码里面的字符串编码问题。只讨论系统运行起来之后,各部分之间的编码问题。

先说Java。
JVM里面的任何字符串资源都是Unicode,就是说,任何String类型的数据都是Unicode编码。没有例外。既然只有一种编码,那么,我们可以这么说,JVM里面的String是不带编码的。String相当于 char[]。
JVM里面的 byte[] 数据是带编码的。比如,Big5,GBK,GB2312,UTF-8之类的。
一个GBK编码的byte[] 转换成 String,其实就是从GBK编码向Unicode编码转换。
一个String转换成一个Big5编码的byte[],其实就是从Unicode编码向Big5编码转换。
所以,Unicode是所有编码转换的中间介质。所有的编码都有一个转换器可以转换到Unicode,而Unicode也可以转换到其他所有的编码。这样构成了一个总线结构。
比如,如果总共有10种编码,那么只需要 10 + 10 = 20个转换器就够了。如果要是两两直接转换,那么,需要的转换器数量是一个组合数字,需要90个转换器。

一个系统的不同部分,都有自己的编码。比如,数据库,文件,JVM,浏览器这4个部分。
在这些部分之间数据交换的地方,就会出现编码问题。比如,数据库和JVM之间,文件和JVM之间,浏览器和JVM之间。这些问题的原理都是相通的。

编码问题最容易处理的地方是文件和JVM之间。文件IO API带有encoding 参数,请自行查阅。
最不容易出现编码问题的地方是数据库和JVM之间。这应该是数据库JDBC连接的基本功能。本文不专门进行讨论。
最容易出问题的地方是浏览器和服务器JVM之间(其实,代码里面的字符串更容易出问题,不过,我已经事先声明,本文不讨论代码中的字符串编码)。下面主要讨论这块浏览器和服务器JVM之间的编码问题。

我们把浏览器编码叫做 Browser_Charset,把JVM编码叫做JVM_Charset(通常等于服务器系统编码)。
当浏览器的数据过来的时候,是一个带有Browser_Charset的byte[]。
如果用户处理程序需要一个String类型的数据,那么JVM会好心好意地把这个byte[]转换成String。使用的转换器是 JVM_Charset -> Unicode。
注意,如果这个时候,Browser_Charset 和 JVM_Charset并不相等。那么,这个自动转换是错误的。
为了弥补这个错误。我们需要做两步工作。
(1) Unicode -> JVM_Charset,把这个String 转换回到原来的 byte[]。
(2) Browser_Charset -> Unicode,把这个还原的byte[]转换成 String。

这个效果,和直接从HTTP Request取得byte[],然后执行 (2) Browser_Charset -> Unicode 的效果是一样的。

如果在Request里面设置了CharacterEncoding,那么POST Data参数就不需要自己手工转换了,web server的自动转换就是正确的。URL的参数编码还涉及到URL编码,需要考虑的问题多一些,没有这么简单。

JVM把数据发到浏览器的时候。也需要考虑编码问题。可以在Response里面设置。另外,HTML Meta Header里面也可以设置编码,提醒Browser选择正确编码。

有些语言的VM或者解释器的字符串编码可能不同。比如,Ruby。不过,编码转换原理都是一样的。

That is all.

 

有关编码的一些问题

java中编码问题详解
  • u011459278
  • u011459278
  • 2015年10月17日 15:27
  • 668

关于编码问题的深度解析

关于编码问题(乱码)的深度解析 编码问题的产生其实都是I/O操作导致的问题,也就是说所有I/O存在的地方就有可能会出现编码问题。 所以要想深度解析编码问题,我们就必须回到源码的实现机制,找到I/O操...
  • sundaysunshine
  • sundaysunshine
  • 2016年12月31日 12:35
  • 376

多元Huffman编码问题

#include #include #include #include using namespace std;/* 每次选最小的k个元素进行合并。与2元Huffman算法类似 */...
  • u012319493
  • u012319493
  • 2015年11月25日 09:46
  • 1071

令人抓狂的编码问题

一直以来,编码问题都是比较令人纠结的,我自己也是,迷惑了好一段时间。 首先这里推荐一篇文章,...
  • zj510
  • zj510
  • 2014年08月04日 15:22
  • 8476

python的编码问题2

编码问题 因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这个机会算是彻底搞清楚了。 问题要从文字的编码讲起。原本的英文编码只有0~255,刚好是8位1个字节。为了表示各种不同的语言,自然要...
  • zhengalen
  • zhengalen
  • 2016年05月10日 20:56
  • 361

支付宝接口编码不规范问题

支付宝平台接口使用了不规范的方式,导致flask不能正常处理的问题解决。
  • Raptor
  • Raptor
  • 2016年09月14日 00:07
  • 1723

哈夫曼编码时遇到的一些问题

我被自己神奇地坑了       好久没写东西了。这些天都在编Huffman编码树,遇到一些问题,发现原来都是在坑自己。 首先是以下代码无法正常读取文本文件     ...
  • u014006264
  • u014006264
  • 2014年06月30日 09:58
  • 1134

理解和解决Python2中的编码问题

前言经常处理一些文本,处理英文语料没什么问题,但是到了中文这儿就让人抓狂了,稍微不注意就会窜出各种乱码错误,平时出现几个小错误试试调调也能过去,但是对于编码这个问题还是畏惧,这几天好好整理了一下pyt...
  • u010223750
  • u010223750
  • 2017年02月25日 18:09
  • 1506

字符编码问题

用比较简单的话来说就是,Unicode定义了所有可以用来表示字符的数值集合(称之为Code Point)。UTF-8和UTF-16等UTF标准定义了这些数值和字符的映射关系。 ASCII字符集:...
  • andyhuabing
  • andyhuabing
  • 2015年11月04日 14:56
  • 1795

爬虫遇见的编码问题汇总

问题1 中文:北京 在浏览器(chrome)中被转换成 %B1%B1%BE%A9 同时打开浏览器中发现 (unable to decode value) 解决方法: 通过: URI.d...
  • Richar1
  • Richar1
  • 2016年03月17日 16:25
  • 795
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编码问题
举报原因:
原因补充:

(最多只允许输入30个字)