Chinaunix首页 | 论坛 | 博客
  • 博客访问: 277670
  • 博文数量: 65
  • 博客积分: 3091
  • 博客等级: 中校
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2005-01-25 09:44
文章存档

2013年(2)

2012年(11)

2011年(12)

2010年(13)

2009年(15)

2008年(12)

分类:

2009-04-13 11:05:08

本地环境(locale)和字符集(charset)设置

locale这个单词中文翻译成地区或者地域,其实这个单词包含的意义要宽泛很多。locale是国际化与本土化过程中的一个非常重要的概念。对于中文用户来说,通常会涉及到的国际化或者本土化,大致包含三个方面:阅读中文,书写中文,与网络中其他系统的交互和通信。locale的设定与中文显示关系不大,但是与中文输入,及存储分区的挂载方式有很密切的关系。例如一个英文环境的Windows不需要设定locale就能够浏览中文,日文或者意大利文网页,也可以显示中文。
设定locale与你能否浏览中文的网页没有直接的关系,即便你把locale设置成 en_US.ISO-8859-1这样一个标准的英文locale你照样可以浏览中文的网页,只要你的系统里面有相应的字符集(这个都不一定需要)和合适的字体(如simsun),浏览器就可以把网页翻译成中文显示出来。具体的过程是网络把网页传送到你的机器上之后,浏览器会判断相应的编码的字符集,根据网页采用的字符集,去字体库里面找合适的字体,然后由文字渲染工具把相应的文字在屏幕上显示出来。

为什么要设定locale以及如何设定呢?有这样一个有意思的问题,为什么gentoo官方论坛上中文论坛的网页是用UTF-8编码的(虽然大家一直强烈建议用GB2312编码),但是新浪网就是用GB2312编码的呢?而Xorg的官方网页竟然是ISO-8859-15编码的,我没有设定这个locale为什么照样能浏览呢?这个问题就像是你有所有的密码本,不论某个网站是用什么字符集编码的,你都可以用你手里的密码本把他们翻译过来,但问题是虽然你能浏览中文网页,但是在整个操作系统里面流动的还是英文字符。所以,就像你能听懂英语,也能听懂中文,但你不可以写中文。

当你决定要写什么东西的时候,首先要决定的一件事情是用那种语言,对于计算机来说就是你要是用哪一种字符集,那你就必须告诉你的linux系统,你想用哪一本密码本去写你想要写的东西。这就是为什么要用GB2312字符集(或兼容它的字符集)去浏览新浪网页的原因,因为它是用GB2312写的。

为了让你的Linux能够输入中文,就需要把系统的locale设定成中文的(严格说来是locale中的语言类别LC_CTYPE ),例如 zh_CN.GB2312、zh_CN.GB18030或者zh_CN.UTF-8。

在计算机术语中,Locale是根据用户所使用的语言,所在国家或者地区,以及当地的文化传统所定义的一个软件运行时的语言环境。

user@host:~$ locale
LANG=zh_CN
LANGUAGE=zh_CN:zh
LC_CTYPE="zh_CN.GBK"
LC_NUMERIC="zh_CN.GBK"
LC_TIME="zh_CN.GBK"
LC_COLLATE="zh_CN.GBK"
LC_MONETARY="zh_CN.GBK"
LC_MESSAGES="zh_CN.GBK"
LC_PAPER="zh_CN.GBK"
LC_NAME="zh_CN.GBK"
LC_ADDRESS="zh_CN.GBK"
LC_TELEPHONE="zh_CN.GBK"
LC_MEASUREMENT="zh_CN.GBK"
LC_IDENTIFICATION="zh_CN.GBK"
LC_ALL=zh_CN.GBK
user@host:~$

locale把按照所涉及到的文化传统的各个方面分成12个大类,这12个大类分别是:

1、语言符号及其分类(LC_CTYPE)
2、数字(LC_NUMERIC)
3、比较和排序习惯(LC_COLLATE)
4、时间显示格式(LC_TIME)
5、货币单位(LC_MONETARY)
6、信息主要是提示信息,错误信息,状态信息,标题,标签,按钮和菜单等(LC_MESSAGES)
7、姓名书写方式(LC_NAME)
8、地址书写方式(LC_ADDRESS)
9、电话号码书写方式(LC_TELEPHONE)
10、度量衡表达方式 (LC_MEASUREMENT)
11、默认纸张尺寸大小(LC_PAPER)
12、对locale自身包含信息的概述(LC_IDENTIFICATION)。

所以说,locale就是某一个地域内的人们的语言习惯和文化传统和生活习惯。一个地区的locale就是根据这几大类的习惯定义的,这些locale定义文件放在/usr/share/i18n/locales目录下面,例如en_US, zh_CN and de_DE@euro都是locale的定义文件,这些文件都是用文本格式书写的,你可以用写字板打开,看看里边的内容,当然出了有限的注释以外,大部分东西可能你都看不懂,因为是用的Unicode的字符索引方式。

user@host:~$ cd /usr/share/i18n/locales
ems@wfsrv:/usr/share/i18n/locales$ ls
aa_DJ           de_CH       eu_FR@euro      lo_LA       ss_ZA
aa_ER           de_DE       fa_IR           lt_LT       st_ZA
aa_ER@saaho     de_DE@euro  fi_FI           lv_LV       sv_FI
aa_ET           de_LU       fi_FI@euro      mg_MG       sv_FI@euro
af_ZA           de_LU@euro  fo_FO           mi_NZ       sv_SE
am_ET           dz_BT       fr_BE           mk_MK       ta_IN
an_ES           el_CY       fr_BE@euro      ml_IN       te_IN
ar_AE           el_GR       fr_CA           mn_MN       tg_TJ
ar_BH           el_GR@euro  fr_CH           mr_IN       th_TH
ar_DZ           en_AU       fr_FR           ms_MY       ti_ER
ar_EG           en_BW       fr_FR@euro      mt_MT       ti_ET
ar_IN           en_CA       fr_LU           nb_NO       tig_ER
ar_IQ           en_DK       fr_LU@euro      ne_NP       tl_PH
ar_JO           en_GB       ga_IE           nl_BE       tn_ZA
ar_KW           en_HK       ga_IE@euro      nl_BE@euro  translit_circle
ar_LB           en_IE       gd_GB           nl_NL       translit_cjk_compat
ar_LY           en_IE@euro  gez_ER          nl_NL@euro  translit_cjk_variants
ar_MA           en_IN       gez_ER@abegede  nn_NO       translit_combining
ar_OM           en_NZ       gez_ET          no_NO       translit_compat
ar_QA           en_PH       gez_ET@abegede  nr_ZA       translit_font
ar_SA           en_SG       gl_ES           nso_ZA      translit_fraction
ar_SD           en_US       gl_ES@euro      oc_FR       translit_hangul
ar_SY           en_ZA       gu_IN           om_ET       translit_narrow
ar_TN           en_ZW       gv_GB           om_KE       translit_neutral
ar_YE           eo          he_IL           or_IN       translit_small
as_IN           es_AR       hi_IN           pa_IN       translit_wide
az_AZ           es_BO       hr_HR           pa_PK       tr_CY
be_BY           es_CL       hsb_DE          pl_PL       tr_TR
be_BY@latin     es_CO       hu_HU           POSIX       ts_ZA
bg_BG           es_CR       hy_AM           pt_BR       tt_RU
bn_BD           es_DO       i18n            pt_PT       uk_UA
bn_IN           es_EC       ia              pt_PT@euro  ur_PK
br_FR           es_ES       id_ID           ro_RO       uz_UZ
br_FR@euro      es_ES@euro  is_IS           ru_RU       uz_UZ@cyrillic
bs_BA           es_GT       iso14651_t1     ru_UA       ve_ZA
byn_ER          es_HN       it_CH           rw_RW       vi_VN
ca_AD           es_MX       it_IT           sa_IN       wa_BE
ca_ES           es_NI       it_IT@euro      se_NO       wa_BE@euro
ca_ES@euro      es_PA       iw_IL           sid_ET      wal_ET
ca_ES@valencia  es_PE       ja_JP           si_LK       wo_SN
ca_FR           es_PR       ka_GE           sk_SK       xh_ZA
ca_IT           es_PY       kk_KZ           sl_SI       yi_US
csb_PL          es_SV       kl_GL           so_DJ       zh_CN
cs_CZ           es_US       km_KH           so_ET       zh_HK
cy_GB           es_UY       kn_IN           so_KE       zh_SG
da_DK           es_VE       ko_KR           so_SO       zh_TW
de_AT           et_EE       ku_TR           sq_AL       zu_ZA
de_AT@euro      eu_ES       kw_GB           sr_CS
de_BE           eu_ES@euro  ky_KG           sr_ME
de_BE@euro      eu_FR       lg_UG           sr_RS
user@host:/usr/share/i18n/locales$

对于de_DE@euro的一点说明,@后边是修正项,也就是说你可以看到两个德国的locale:/usr /share/i18n/locales/de_DE@euro和/usr/share/i18n/locales/de_DE。打开这两个locale定义,你就会知道它们的差别在于 de_DE@euro使用的是欧洲的排序、比较和缩进习惯,而de_DE用的是德国的标准习惯。

Locale 是软件在运行时的语言环境, 它包括语言(Language), 地域 (Territory) 和字符集(Codeset)。一个locale的书写格式为: 语言[_地域[.字符集]]. 所以说呢,locale总是和一定的字符集相联系的。

设定locale就是设定12大类的locale分类属性,即12个LC_XXX。除了这12个变量可以设定以外,为了简便起见,还有两个变量:LC_ALL和LANG。它们之间有一个优先级的关系:LC_ALL > LC_* >LANG。可以这么说,LC_ALL是最上级设定或者强制设定,而LANG是默认设定值。

1、如果你设定了LC_ALL=zh_CN.UTF-8,那么不管LC_*和LANG设定成什么值,它们都会被强制服从LC_ALL的设定,成为 zh_CN.UTF-8。

2、假如你设定了LANG=zh_CN.UTF-8,而其他的LC_*=en_US.UTF-8,并且没有设定LC_ALL的话,那么系统的locale设定以LC_*=en_US.UTF-8。

3、假如你设定了LANG=zh_CN.UTF-8,而其他的LC_*,和LC_ALL均未设定的话,系统会将LC_*设定成默认值,也就是LANG的值zh_CN.UTF-8。

4、假如你设定了LANG=zh_CN.UTF-8,而其他的LC_CTYPE=en_US.UTF-8,其他的LC_*,和LC_ALL均未设定的话,那么系统的locale设定将是:LC_CTYPE=en_US.UTF-8,其余的 LC_COLLATE,LC_MESSAGES等等均会采用默认值,也就是 LANG的值,也就是LC_COLLATE=LC_MESSAGES=……= LC_PAPER=LANG=zh_CN.UTF-8。

另外非常重要的一点就是这些分类是彼此独立的,也就是说LC_CTYPE,LC_COLLATE和 LC_MESSAGES等等分类彼此之间是独立的,可以根据用户的需要设定成不同的值。这一点对很多用户是有利的,甚至是必须的。

如果你需要一个纯中文的系统的话,设定LC_ALL= zh_CN.XXXX,或者LANG= zh_CN.XXXX都可以,当然你可以两个都设定,但正如上面所讲,LC_ALL的值将覆盖所有其他的locale设定,不用作无用功。
如果只需要一个能够输入中文的英文环境,那么可以把 LC_CTYPE设定成zh_CN.GB18030,而其他所有的项都是en_US.UTF-8。
假如你高兴的话,可以把12个LC_XXX 一一设定成你需要的值,打造一个古灵精怪的系统: LC_CTYPE=zh_CN.GBK/GBK(使用中文编码内码GBK字符集); LC_NUMERIC=en_GB.ISO-8859-1(使用大不列颠的数字系统) LC_MEASUREMEN=de_DE@euro.ISO-8859-15(德国的度量衡使用ISO-8859-15字符集) 罗马的地址书写方式,美国的纸张设定……。
假如你什么也不做的话,也就是LC_ALL,LANG和LC_XXX均不指定特定值的话,系统将采用POSIX作为lcoale,也就是C locale。


了解一种字符集编码主要是要了解该编码的编码范围,编码对应的字符集(都包含哪些字符),和其他字符集编码之间的关系等。

charset
    字符集,顾名思义是字符的集合,它包括了一系列字符,并对每个字符设置了相应的编号(注意,编号不是最终的编码)。
encoding
    编码,与字符集相对应的储存和传输的编码格式,它会将字符集中的每个字符,储存为相应的二进制字节。编码与解码总是呼应的,即一个编码方式同时也包含了将字符从风二进制编码中还原的使命。
codpage
    代码页,是从系统内码表到相应编码的映射表,比如 MS936 就是从 UTF-8(这是 Windows 系统的内码)到 GBK 的映射表。

ASCII

ASCII码是7位编码,编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。

只支持ASCII码的系统会忽略每个字节的最高位,只认为低7位是有效位。HZ字符编码就是早期为了在只支持7位ASCII系统中传输中文而设计的编码。早期很多邮件系统也只支持ASCII编码,为了传输中文邮件必须使用BASE64或者其他编码方式。

GB2312

GB2312是基于区位码设计的,区位码把编码表分为94个区,每个区对应94个位,每个字符的区号和位号组合起来就是该汉字的区位码。区位码一般用10进制数来表示,如1601就表示16区1位,对应的字符是“啊”。在区位码的区号和位号上分别加上0xA0就得到了GB2312编码。

区位码中01-09区是符号、数字区,16-87区是汉字区,10-15和88-94是未定义的空白区。它将收录的汉字分成两级:第一级是常用汉字计3755个,置于16-55区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计3008个,置于56-87区,按部首/笔画顺序排列。一级汉字是按照拼音排序的,这个就可以得到某个拼音在一级汉字区位中的范围,很多根据汉字可以得到拼音的程序就是根据这个原理编写的。

GB2312字符集中除常用简体汉字字符外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符,未收录繁体中文汉字和一些生僻字。可以用繁体汉字测试某些系统是不是只支持GB2312编码。

GB2312的编码范围是0xA1A1-0x7E7E,去掉未定义的区域之后可以理解为实际编码范围是0xA1A1-0xF7FE。

EUC-CN可以理解为GB2312的别名,和GB2312完全相同。

区位码更应该认为是字符集的定义,定义了所收录的字符和字符位置,而GB2312及EUC-CN是实际计算机环境中支持这种字符集的编码。HZ和ISO-2022-CN是对应区位码字符集的另外两种编码,都是用7位编码空间来支持汉字。区位码和GB2312编码的关系有点像 Unicode和UTF-8。

GBK

GBK编码是GB2312编码的超集,向下完全兼容GB2312,同时GBK收录了Unicode基本多文种平面中的所有CJK汉字。同 GB2312一样,GBK也支持希腊字母、日文假名字母、俄语字母等字符,但不支持韩语中的表音字符(非汉字字符)。GBK还收录了GB2312不包含的汉字部首符号、竖排标点符号等字符。

GBK的整体编码范围是为0x8140-0xFEFE,不包括低字节是0×7F的组合。高字节范围是0×81-0xFE,低字节范围是0x40-7E和0x80-0xFE。

低字节是0x40-0x7E的GBK字符有一定特殊性,因为这些字符占用了ASCII码的位置,这样会给一些系统带来麻烦。

有些系统中用0x40-0x7E中的字符(如“|”)做特殊符号,在定位这些符号时又没有判断这些符号是不是属于某个 GBK字符的低字节,这样就会造成错误判断。在支持GB2312的环境下就不存在这个问题。需要注意的是支持GBK的环境中小于0x80的某个字节未必就是ASCII符号;另外就是最好选用小于0×40的ASCII符号做一些特殊符号,这样就可以快速定位,且不用担心是某个汉字的另一半。Big5编码中也存在相应问题。

GBK全名为汉字内码扩展规范,英文名Chinese Internal Code Specification。K 即是“扩展”所对应的汉语拼音(KuoZhan11)中“扩”字的声母。

CP936是一种操作系统所使用的编码页(Code Page)。CP936和GBK的有些许差别,绝大多数情况下可以把CP936当作GBK的别名。

GB18030

GB18030编码向下兼容GBK和GB2312,兼容的含义是不仅字符兼容,而且相同字符的编码也相同。GB18030收录了所有Unicode3.1中的字符,包括中国少数民族字符,GBK不支持的韩文字符等等,也可以说是世界大多民族的文字符号都被收录在内。

GBK和GB2312都是双字节等宽编码,如果算上和ASCII兼容所支持的单字节,也可以理解为是单字节和双字节混合的变长编码。GB18030编码是变长编码,有单字节、双字节和四字节三种方式。

GB18030的单字节编码范围是0x00-0x7F,完全等同与ASCII;双字节编码的范围和GBK相同,高字节是0x81-0xFE,低字节的编码范围是0x40-0x7E和0x80-FE;四字节编码中第一、三字节的编码范围是0x81-0xFE,二、四字节是0x30-0x39。

Windows中CP936代码页使用0x80来表示欧元符号,而在GB18030编码中没有使用0x80编码位,用其他位置来表示欧元符号。这可以理解为是GB18030向下兼容性上的一点小问题;也可以理解为0x80是CP936对GBK的扩展,而GB18030只是和GBK兼容良好。

从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到 GB18030都属于双字节字符集 (DBCS)。

BIG5

Big5是双字节编码,高字节编码范围是0x81-0xFE,低字节编码范围是0x40-0x7E和0xA1-0xFE。和GBK相比,少了低字节是0x80-0xA0的组合。0x8140-0xA0FE是保留区域,用于用户造字区。

Big5收录的汉字只包括繁体汉字,不包括简体汉字,一些生僻的汉字也没有收录。GBK收录的日文假名字符、俄文字符Big5也没有收录。因为Big5当中收录的字符有限,因此有很多在Big5基础上扩展的编码,如倚天中文系统。Windows系统上使用的代码页CP950也可以理解为是对Big5的扩展,在Big5的基础上增加了7个汉字和一些符号。Big5编码对应的字符集是GBK字符集的子集,也就是说Big5收录的字符是GBK收录字符的一部分,但相同字符的编码不同。

因为Big5也占用了ASCII的编码空间(低字节所使用的0x40-0x7E),所以Big5编码在一些环境下存在和GBK编码相同的问题,即低字节范围为0x40-0x7E的字符有可能会被误处理,尤其是低字节是0x5C("/")和0x7C("|")的字符。可以参考GBK一节相应说明。

尽管有些区别,大多数情况下可以把CP950当作Big5的别名。

ISO-8859-1

ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。

ISO-8859-1收录的字符除ASCII收录的字符外,还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。欧元符号出现的比较晚,没有被收录在ISO-8859-1当中。

因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。 ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。

Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。

UCS-2和UTF-16

Unicode组织和ISO组织都试图定义一个超大字符集,目的是要涵盖所有语言使用的字符以及其他学科使用的一些特殊符号,这个字符集就是通用字符集(UCS,Universal Character Set)。这两个组织经过协调,虽然在各自发展,但定义的字符位置是完全一致的。ISO相应的标准是ISO 10646。Unicode和ISO 10646都在不断的发展过程中,所以会有不同的版本号来标明不同的发展阶段,每个Unicode版本号都能找到相对应的ISO 10646版本号。

ISO 10646标准定义了一个31位的字符集。前两个字节的位置(0x0000-0xFFFD)被称为基本多语言面(Basic Multilingual Plane, BMP),超出两个字节的范围称作辅助语言面。BMP基本包括了所有语言中绝大多数字符,所以只要支持BMP就可以支持绝大多数场合下的应用。Unicode 3.0对应的字符集在BMP范围内。

UCS字符集为每个字符分配了一个位置,通常用“U”再加上某个字符在UCS中位置的16进制数作为这个字符的UCS表示,例如“U+0041”表示字符“A”。UCS字符U+0000到U+00FF与ISO-8859-1完全一致。

UCS-2、UTF-16是UCS字符集(或者说是Unicode字符集)实际应用中的具体编码方式。UCS-2是两个字节的等宽编码,因为只是使用了两个字节的编码空间,所以只能对BMP中的字符做编码。UTF-16是变长编码,用两个字节对BMP内的字符编码,用4个字节对超出BMP范围的辅助平面内的字符作编码。

UCS-2不同于GBK和Big5,它是真正的等宽编码,每个字符都使用两个字节,这个特性在字符串截断和字符数计算时非常方便。

UTF-16是UCS-2的超集,UTF-16编码的两字节编码方式完全和UCS-2相同,也就是说在BMP的框架内UCS-2完全等同与UTF-16。实际情况当中常常把UCS-16当作UCS-2的别名。

UCS-2和UTF-16在存储和传输时会使用两种不同的字节序,分别是big endian和little endian(大尾和小尾)。例如“啊”(U+554A)用big endian表示就是0x554A,用little endian表示就是0x4A55。UCS-2和UTF-16默认的字节序是big endian方式。在传输过程中为了说明字节序需要在字节流前加上BOM(Byte order Mark),0xFEFF表示是big endian,0xFFFE表示是little endian。UCS-2BE、UCS-2LE是实际应用中使用的编码名称,对应着big endian和little endian,UTF-16BE、UTF-16LE也是如此。因为默认是BE字节序,所以可以把UCS-2当做是UCS-2BE的别名。

在UCS编码中有一个叫做“ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是U+FEFF,是个没有实际意义的字符。UCS规范建议我们在传输字节流前,先传输字符“ZERO WIDTH NO-BREAK SPACE”,如果传输的ZERO WIDTH NO-BREAK SPACE是0xFEFF就说明是big endian,反之就是little endian。

UCS-2和UTF-16也可以理解为和ASCII以及ISO-8859-1兼容,在ASCII编码或者ISO-8859-1编码的每个字节前加上0x00,就得到相应字符的UCS-2编码。

UCS-2和UTF-16中会使用0x00作为某个字符编码的一部分,某些系统会把0x00当作字符串结束的标志,在处理UCS-2或UTF-16编码时会出现问题。

UTF-8

UTF-8是UCS字符集的另一种编码方式,UTF-16的每个单元是两个字节(16位),而UTF-8的每个单元是一个字节(8位)。UTF-16中用一个或两个双字节表示一个字符,UTF-8中用一个或几个单字节表示一个字符。

可以认为UTF-8编码是根据一定规律从UCS-2转换得到的,从UCS-2到UTF-8之间有以下转换关系:

UCS-2 UTF-8
U+0000 - U+007F 0xxxxxxx
U+0080 - U+07FF 110xxxxx 10xxxxxx
U+0800 - U+FFFF 1110xxxx 10xxxxxx 10xxxxxx


例如“啊”字的UCS-2编码是0x554A,对应的二进制是0101 0101 0100 1010,转成UTF-8编码之后的二进制是1110 0101 10 010101 10 001010,对应的十六进制是0xE5958A。

UCS-4也是一种UCS字符集的编码方式,是使用4个字节的等宽编码,可以用UCS-4来表示BMP之外的辅助面字符。UCS-2中每两个字节前再加上 0x0000就得到了BMP字符的UCS-4编码。从UCS-4到UTF-8也存在转换关系,根据这种转换关系,UTF-8最多可以使用六个字节来编码 UCS-4。

根据UTF-8的生成规律和UCS字符集的特性,可以看到UTF-8具有的特性:

UTF-8完全和ASCII兼容,也就是说ASCII对应的字符在UTF-8中和ASCII编码完全一致。范围在0x00-0x7F之内的字符一定是ASCII字符,不可能是其他字符的一部分。GBK和Big5都存在的缺陷在UTF-8中是不存在的。
大于U+007F的UCS字符,在UTF-8编码中至少是两个字节。
UTF-8中的每个字符编码的首字节总在0x00-0xFD之间(不考虑UCS-4支持的情况,首字节在0x00-0xEF之间)。根据首字节就可以判断之后连续几个字节。
非首字节的其他字节都在0x80-0xBF之间;0xFE和0xFF在UTF-8中没有被用到。
GBK编码中的汉字字符都在UCS-2中的范围都在U+0800 - U+FFFF之间,所以每个GBK编码中的汉字字符的UTF-8编码都是3个字节。但GBK中包含的其他字符的UTF-8编码就不一定是3个字节了,如GBK中的俄文字符。
在UTF-8的编码的传输过程中即使丢掉一个字节,根据编码规律也很容易定位丢掉的位置,不会影响到其他字符。在其他双字节编码中,一旦损失一个字节,就会影响到此字节之后的所有字符。从这点可以看出UTF-8编码非常适合作为传输编码。

关于字符集的参考资料:



Name: GBK
MIBenum: 113
Source: Chinese IT Standardization Technical Committee
Please see:
Alias: CP936
Alias: MS936
Alias: windows-936

Name: GB18030
MIBenum: 114
Source: Chinese IT Standardization Technical Committee
Please see:
Alias: None

阅读(2946) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~