天道酬勤

GB2312/GBK/GB18030/BIG5/UNICODE/UTF-8编码

上一篇 / 下一篇  2007-07-26 11:00:45 / 个人分类:术语词库

51Testing软件测试网4|u @~]:DICX

经常会碰到一些关于编码的名词,特意收录了些资料以备查阅。51Testing软件测试网^'y:\aC(m q1IU^

51Testing软件测试网P6hA5TLN5AEf

GB2312:简体中文编码51Testing软件测试网I.YJ:` B3c"y

9`8p,rD8\dW-oxo0GBK: GB2312的扩展

V}3G6wd3@Sm/[0

\P&R0]ux A3hg0GB18030: GBK的扩展

i0v(J/qr0

yn W)z;Mt0BIG5: 繁体中文编码51Testing软件测试网;S/R-_C#J j0_ o e

\DT!F1ox ]3y2{4h*e0UNICODE: 国际通用字符集51Testing软件测试网(PsBj5o?c+B

7xzrO{0UTF-8: 国际通用字符编码51Testing软件测试网BV~:A VB$ll Mj

(E3t;pz4Tu)K|4y0附1:字符集与编码

&w/pv;P#mR0

[(R0a3[+rD0
Lr |#^ o$Z4S-?+t0各个国家和地区所制定的不同 ANSI 编码标准中,都只规定了各自语言所需的“字符”。比如:汉字标准(GB2312)中没有规定韩国语字符怎样存储。这些 ANSI 编码标准所规定的内容包含两层含义:51Testing软件测试网5cQ"a)J5CUsk'T7mY
1. 使用哪些字符。也就是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“字符集”。
U(B zN&o/T/`sS8}^02. 规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码”。
%abJ7wHov#Er l0各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。
I#L&E-K.e VK7U0“UNICODE 字符集”包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。
.d?n zJ8hN9T'd#b051Testing软件测试网#A%YvY!z

51Testing软件测试网&x4RO%ia!g/T

附2:编码原理51Testing软件测试网y8J&PuY-XSl1H

51Testing软件测试网w mD3S"D*_c0[U'_!\

编码无处不在。Database, file, editor, IDE, compiler, browser。
QFx;i }2y!v`"C0代码(比如java, jsp, asp, php, python, ruby etc)里面的字符串比较麻烦,涉及到editor, compiler, interpreter等等。51Testing软件测试网jL8QV9ugx
所以,我的做法是,从来不在代码里面直接写字符串资源,尤其是双字节编码的字符串资源。51Testing软件测试网Rnk,{5b
都是把字符串资源分离到一个单独的资源文件里面。这样,只需要照管这个文件的编码就够了。
!B'Az!cj7h0需要注意的一点是,文件里面、数据库里面、网络传输需要的数据,都是byte[]。51Testing软件测试网;e.CA^9l vg
以下的讨论,不涉及代码里面的字符串编码问题。只讨论系统运行起来之后,各部分之间的编码问题。

%~ VQYh;x,n,K0

*i"nu&p#t1f2o.k0先说Java。
r[8l8f \$?$D)]0JVM里面的任何字符串资源都是Unicode,就是说,任何String类型的数据都是Unicode编码。没有例外。既然只有一种编码,那么,我们可以这么说,JVM里面的String是不带编码的。String相当于 char[]。51Testing软件测试网4mvBrFq:H
JVM里面的 byte[] 数据是带编码的。比如,Big5,GBK,GB2312,UTF-8之类的。51Testing软件测试网'niY~{H,@m{M&ZA
一个GBK编码的byte[] 转换成 String,其实就是从GBK编码向Unicode编码转换。51Testing软件测试网-s&}Cn{
一个String转换成一个Big5编码的byte[],其实就是从Unicode编码向Big5编码转换。
-Re;Yyi _yHD#d i0所以,Unicode是所有编码转换的中间介质。所有的编码都有一个转换器可以转换到Unicode,而Unicode也可以转换到其他所有的编码。这样构成了一个总线结构。
Lt%Ht.E6jLe0比如,如果总共有10种编码,那么只需要 10 + 10 = 20个转换器就够了。如果要是两两直接转换,那么,需要的转换器数量是一个组合数字,需要90个转换器。

~&\t'e,z)r_M051Testing软件测试网6N {*o#k&U,YG

一个系统的不同部分,都有自己的编码。比如,数据库,文件,JVM,浏览器这4个部分。
G:gu#kch,S0在这些部分之间数据交换的地方,就会出现编码问题。比如,数据库和JVM之间,文件和JVM之间,浏览器和JVM之间。这些问题的原理都是相通的。51Testing软件测试网O5IM){['|e+zH

51Testing软件测试网WE,nM q

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

Ll(z:G o0H)O051Testing软件测试网Zi-p ~ z#J&_

我们把浏览器编码叫做 Browser_Charset,把JVM编码叫做JVM_Charset(通常等于服务器系统编码)。51Testing软件测试网:I$B[$a r9KZ
当浏览器的数据过来的时候,是一个带有Browser_Charset的byte[]。
"Qq;pM\n)W3g6x0如果用户处理程序需要一个String类型的数据,那么JVM会好心好意地把这个byte[]转换成String。使用的转换器是 JVM_Charset -> Unicode。
f$} Rz~6w DXQfz x0注意,如果这个时候,Browser_Charset 和 JVM_Charset并不相等。那么,这个自动转换是错误的。
)r[XK|}0为了弥补这个错误。我们需要做两步工作
L o-JKp@]&?(Sa$G0(1) Unicode -> JVM_Charset,把这个String 转换回到原来的 byte[]。51Testing软件测试网/Qdh2J#y6Q'n
(2) Browser_Charset -> Unicode,把这个还原的byte[]转换成 String。51Testing软件测试网p6f1pzG.?

&A.L[6WL7l0这个效果,和直接从HTTP Request取得byte[],然后执行 (2) Browser_Charset -> Unicode 的效果是一样的。51Testing软件测试网lekP9T;vL UcQ"v

51Testing软件测试网Tb}#?v

如果在Request里面设置了CharacterEncoding,那么POST Data参数就不需要自己手工转换了,web server的自动转换就是正确的。URL的参数编码还涉及到URL编码,需要考虑的问题多一些,没有这么简单。51Testing软件测试网},x(Yh'W|D ?#]

51Testing软件测试网oJR2C5o7iH

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

xQUS!s5N0

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

|P4YCdl!b0
相关阅读:

TAG: 术语词库

 

评分:0

我来说两句

日历

« 2024-04-26  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 41225
  • 日志数: 65
  • 图片数: 1
  • 文件数: 2
  • 书签数: 13
  • 建立时间: 2006-12-27
  • 更新时间: 2008-05-31

RSS订阅

Open Toolbar