Unicode、UTF-8 和 ISO8859-1


 

2.1. iso8859-1 

属于单字节编码,最多能表示的字符范围是

0-255

,应用于英文系列。比如,字母

a

的编码

0x61=97

 

很明显,

iso8859-1

编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编

码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用

iso8859-1

编码来表示。而

且在很多协议上,

默认使用该编码。

比如,

虽然

"

中文

"

两个字不存在

iso8859-1

编码,

gb2312

编码为例,应该是

"d6d0 cec4"

两个字符,使用

iso8859-1

编码的时候则将它拆开为

4

个字节

来表示:

"d6 d0 ce c4"

(事实上,在进行存储的时候,也是以字节为单位处理的)

。而如果是

UTF

编码,则是

6

个字节

"e4 b8 ad e6 96 87"

。很明显,这种表示方法还需要以另一种编码为

基础。

 

2.2. GB2312/GBK 

这就是汉子的国标码,

专门用来表示汉字,

是双字节编码,

而英文字母和

iso8859-1

一致

(兼

iso8859-1

编码)

。其中

gbk

编码能够用来同时表示繁体字和简体字,而

gb2312

只能表示

简体字,

gbk

是兼容

gb2312

编码的。

 

2.3. unicode 

这是最统一的编码,

可以用来表示所有语言的字符,而且是定长双字节

(也有四字节的)编

码,包括英文字母在内。所以可以说它是不兼容

iso8859-1

编码的,也不兼容任何编码。不

过,相对于

iso8859-1

编码来说,

uniocode

编码只是在前面增加了一个

0

字节,比如字母

a

"00 61"

 

需要说明的是,定长编码便于计算机处理(注意

GB2312/GBK

不是定长编码)

,而

unicode

又可以用来表示所有字符,所以在很多软件内部是使用

unicode

编码来处理的,比如

java

 

2.4. UTF 

考虑到

unicode

编码不兼容

iso8859-1

编码,

而且容易占用更多的空间:

因为对于英文字母,

unicode

也需要两个字节来表示。所以

unicode

不便于传输和存储。因此而产生了

utf

编码,

utf

编码兼容

iso8859-1

编码,同时也可以用来表示所有语言的字符,不过,

utf

编码是不定

长编码,每一个字符的长度从

1-6

个字节不等。另外,

utf

编码自带简单的校验功能。一般

来讲,英文字母都是用一个字节表示,而汉字使用三个字节。

 

注意,虽然说

utf

是为了使用更少的空间而使用的,但那只是相对于

unicode

编码来说,如

果已经知道是汉字,则使用

GB2312/GBK

无疑是最节省的。不过另一方面,值得说明的是,

虽然

utf

编码对汉字使用

3

个字节,

但即使对于汉字网页,

utf

编码也会比

unicode

编码节省,

因为网页中包含了很多的英文字符。

 

3. java

对字符的处理

 

java

应用软件中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地

方需要进行一定程度的处理。

 

3.1. getBytes(charset) 

这是

java

字符串处理的一个标准函数,其作用是将字符串所表示的字符按照

charset

编码,

并以字节方式表示。注意字符串在

java

内存中总是按

unicode

编码存储的。比如

"

中文

"

,正

常情况下

(即没有错误的时候)

存储为

"4e2d 6587"

如果

charset

"gbk"

则被编码为

"d6d0 

cec4"

,然后返回字节

"d6 d0 ce c4"

。如果

charset

"utf8"

则最后是

"e4 b8 ad e6 96 87"

。如果

"iso8859-1"

,则由于无法编码,最后返回

 

"3f 3f"

(两个问号)

 

3.2. new String(charset) 

这是

java

字符串处理的另一个标准函数,

和上一个函数的作用相反,

将字节数组按照

charset

编码进行组合识别,最后转换为

unicode

存储。参考上述

getBytes

的例子,

"gbk" 

"utf8"

都可以得出正确的结果

"4e2d 6587"

,但

iso8859-1

最后变成了

"003f 003f"

(两个问号)

 

因为

utf8

可以用来表示

/

编码所有字符,

所以

new String( str.getBytes( "utf8" ), "utf8" ) === str

即完全可逆。

 

3.3. setCharacterEncoding() 

该函数用来设置

http

请求或者相应的编码。

 

对于

request

,是指提交内容的编码,指定后可以通过

getParameter()

则直接获得正确的字符

串,如果不指定,则默认使用

iso8859-1

编码,需要进一步处理。参见下述

"

表单输入

"

。值

得注意的是在执行

setCharacterEncoding()

之前,不能执行任何

getParameter()

java doc

上说

明:

This 

method 

must 

be 

called 

prior 

to 

reading 

request 

parameters 

or 

reading 

input 

using 

getReader()

。而且,该指定只对

POST

方法有效,对

GET

方法无效。分析原因,应该是在执

行第一个

getParameter()

的时候,

java

将会按照编码分析所有的提交内容,而后续的

getParameter()

不再进行分析,

所以

setCharacterEncoding()

无效。

而对于

GET

方法提交表单是,

提交的内容在

URL

中,一开始就已经按照编码分析所有的提交内容,

setCharacterEncoding()

自然就无效。

 

对于

response

,则是指定输出内容的编码,同时,该设置会传递给浏览器,告诉浏览器输出

内容所采用的编码

本文主要包括以下几个方面:编码基本知识,

java

,系统软件,

url

,工具软件等。

 

在下面的描述中,将以

"

中文

"

两个字为例,经查表可以知道其

GB2312

编码是

"d6d0 cec4"

Unicode

编码为

"4e2d 6587"

UTF

编码就是

"e4b8ad e69687"

注意,

这两个字没有

iso8859-1

编码,但可以用

iso8859-1

编码来

"

表示

"

 

2. 

编码基本知识

 

最早的编码是

iso8859-1

,和

ascii

编码相似。但为了方便表示各种各样的语言,逐渐出现了

很多标准编码,重要的有如下几个。

 

2.1. iso8859-1 

属于单字节编码,最多能表示的字符范围是

0-255

,应用于英文系列。比如,字母

a

的编码

0x61=97

 

很明显,

iso8859-1

编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编

码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用

iso8859-1

编码来表示。而

且在很多协议上,

默认使用该编码。

比如,

虽然

"

中文

"

两个字不存在

iso8859-1

编码,

gb2312

编码为例,应该是

"d6d0 cec4"

两个字符,使用

iso8859-1

编码的时候则将它拆开为

4

个字节

来表示:

"d6 d0 ce c4"

(事实上,在进行存储的时候,也是以字节为单位处理的)

。而如果是

UTF

编码,则是

6

个字节

"e4 b8 ad e6 96 87"

。很明显,这种表示方法还需要以另一种编码为

基础。

 

2.2. GB2312/GBK 

这就是汉子的国标码,

专门用来表示汉字,

是双字节编码,

而英文字母和

iso8859-1

一致

(兼

iso8859-1

编码)

。其中

gbk

编码能够用来同时表示繁体字和简体字,而

gb2312

只能表示

简体字,

gbk

是兼容

gb2312

编码的。

 

2.3. unicode 

这是最统一的编码,

可以用来表示所有语言的字符,而且是定长双字节

(也有四字节的)编

码,包括英文字母在内。所以可以说它是不兼容

iso8859-1

编码的,也不兼容任何编码。不

过,相对于

iso8859-1

编码来说,

uniocode

编码只是在前面增加了一个

0

字节,比如字母

a

"00 61"

 

需要说明的是,定长编码便于计算机处理(注意

GB2312/GBK

不是定长编码)

,而

unicode

又可以用来表示所有字符,所以在很多软件内部是使用

unicode

编码来处理的,比如

java

 

2.4. UTF 

考虑到

unicode

编码不兼容

iso8859-1

编码,

而且容易占用更多的空间:

因为对于英文字母,

unicode

也需要两个字节来表示。所以

unicode

不便于传输和存储。因此而产生了

utf

编码,

utf

编码兼容

iso8859-1

编码,同时也可以用来表示所有语言的字符,不过,

utf

编码是不定

长编码,每一个字符的长度从

1-6

个字节不等。另外,

utf

编码自带简单的校验功能。一般

来讲,英文字母都是用一个字节表示,而汉字使用三个字节。

 

注意,虽然说

utf

是为了使用更少的空间而使用的,但那只是相对于

unicode

编码来说,如

果已经知道是汉字,则使用

GB2312/GBK

无疑是最节省的。不过另一方面,值得说明的是,

虽然

utf

编码对汉字使用

3

个字节,

但即使对于汉字网页,

utf

编码也会比

unicode

编码节省,

因为网页中包含了很多的英文字符。

 

3. java

对字符的处理

 

java

应用软件中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地

方需要进行一定程度的处理。

 

3.1. getBytes(charset) 

这是

java

字符串处理的一个标准函数,其作用是将字符串所表示的字符按照

charset

编码,

并以字节方式表示。注意字符串在

java

内存中总是按

unicode

编码存储的。比如

"

中文

"

,正

常情况下

(即没有错误的时候)

存储为

"4e2d 6587"

如果

charset

"gbk"

则被编码为

"d6d0 

cec4"

,然后返回字节

"d6 d0 ce c4"

。如果

charset

"utf8"

则最后是

"e4 b8 ad e6 96 87"

。如果

"iso8859-1"

,则由于无法编码,最后返回

 

"3f 3f"

(两个问号)

 

3.2. new String(charset) 

这是

java

字符串处理的另一个标准函数,

和上一个函数的作用相反,

将字节数组按照

charset

编码进行组合识别,最后转换为

unicode

存储。参考上述

getBytes

的例子,

"gbk" 

"utf8"

都可以得出正确的结果

"4e2d 6587"

,但

iso8859-1

最后变成了

"003f 003f"

(两个问号)

 

因为

utf8

可以用来表示

/

编码所有字符,

所以

new String( str.getBytes( "utf8" ), "utf8" ) === str

即完全可逆。

 

3.3. setCharacterEncoding() 

该函数用来设置

http

请求或者相应的编码。

 

对于

request

,是指提交内容的编码,指定后可以通过

getParameter()

则直接获得正确的字符

串,如果不指定,则默认使用

iso8859-1

编码,需要进一步处理。参见下述

"

表单输入

"

。值

得注意的是在执行

setCharacterEncoding()

之前,不能执行任何

getParameter()

java doc

上说

明:

This 

method 

must 

be 

called 

prior 

to 

reading 

request 

parameters 

or 

reading 

input 

using 

getReader()

。而且,该指定只对

POST

方法有效,对

GET

方法无效。分析原因,应该是在执

行第一个

getParameter()

的时候,

java

将会按照编码分析所有的提交内容,而后续的

getParameter()

不再进行分析,

所以

setCharacterEncoding()

无效。

而对于

GET

方法提交表单是,

提交的内容在

URL

中,一开始就已经按照编码分析所有的提交内容,

setCharacterEncoding()

自然就无效。

 

对于

response

,则是指定输出内容的编码,同时,该设置会传递给浏览器,告诉浏览器输出

内容所采用的编码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值