`
re_reference
  • 浏览: 237285 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[转]深入了解字符集和编码问题

web 
阅读更多
一、什么是字符集?什么是编码?

字符(Character)是文字与符号的总称,包括文字、图形符号、数学符号等。
一组抽象字符的集合就是字符集(Charset)。
字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集。
一组有共同特征的字符也可以组成字符集,比如繁体汉字字符集、日文汉字字符集。
字符集的子集也是字符集。

计算机要处理各种字符,就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding)。
制定编码首先要确定字符集,并将字符集内的字符排序,然后和二进制数字对应起来。根据字符集内字符的多少,会确定用几个字节来编码。
每种编码都限定了一个明确的字符集合,叫做被编码过的字符集(Coded Character Set),这是字符集的另外一个含义。通常所说的字符集大多是这个含义。

二、有哪些字符集?

ASCII:
American Standard Code for Information Interchange,美国信息交换标准码。
目前计算机中用得最广泛的字符集及其编码,由美国国家标准局(ANSI)制定。
它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。
ASCII字符集由控制字符和图形字符组成。
在计算机的存储单元中,一个ASCII码值占一个字节(8个二进制位),其最高位(b7)用作奇偶校验位。
所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。
奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1。
偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。

ISO 8859-1:
ISO 8859,全称ISO/IEC 8859,是国际标准化组织(ISO)及国际电工委员会(IEC)联合制定的一系列8位字符集的标准,现时定义了15个字符集。
ASCII收录了空格及94个“可印刷字符”,足以给英语使用。
但是,其他使用拉丁字母的语言(主要是欧洲国家的语言),都有一定数量的变音字母,故可以使用ASCII及控制字符以外的区域来储存及表示。
除了使用拉丁字母的语言外,使用西里尔字母的东欧语言、希腊语、泰语、现代阿拉伯语、希伯来语等,都可以使用这个形式来储存及表示。
    * ISO 8859-1 (Latin-1) - 西欧语言
    * ISO 8859-2 (Latin-2) - 中欧语言
    * ISO 8859-3 (Latin-3) - 南欧语言。世界语也可用此字符集显示。
    * ISO 8859-4 (Latin-4) - 北欧语言
    * ISO 8859-5 (Cyrillic) - 斯拉夫语言
    * ISO 8859-6 (Arabic) - 阿拉伯语
    * ISO 8859-7 (Greek) - 希腊语
    * ISO 8859-8 (Hebrew) - 希伯来语(视觉顺序)
    * ISO 8859-8-I - 希伯来语(逻辑顺序)
    * ISO 8859-9 (Latin-5 或 Turkish) - 它把Latin-1的冰岛语字母换走,加入土耳其语字母。
    * ISO 8859-10 (Latin-6 或 Nordic) - 北日耳曼语支,用来代替Latin-4。
    * ISO 8859-11 (Thai) - 泰语,从泰国的 TIS620 标准字集演化而来。
    * ISO 8859-13 (Latin-7 或 Baltic Rim) - 波罗的语族
    * ISO 8859-14 (Latin-8 或 Celtic) - 凯尔特语族
    * ISO 8859-15 (Latin-9) - 西欧语言,加入Latin-1欠缺的法语及芬兰语重音字母,以及欧元符号。
    * ISO 8859-16 (Latin-10) - 东南欧语言。主要供罗马尼亚语使用,并加入欧元符号。
很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。
但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用iso8859-1编码来表示。
而且在很多协议上,默认使用该编码。

UCS:
通用字符集(Universal Character Set,UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的字符编码方式,采用4字节编码。
UCS包含了已知语言的所有字符。
除了拉丁语、希腊语、斯拉夫语、希伯来语、阿拉伯语、亚美尼亚语、格鲁吉亚语,还包括中文、日文、韩文这样的象形文字,UCS还包括大量的图形、印刷、数学、科学符号。
    * UCS-2: 与unicode的2byte编码基本一样。
    * UCS-4: 4byte编码, 目前是在UCS-2前加上2个全零的byte。

Unicode:
Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。
它是http://www.unicode.org制定的编码机制, 要将全世界常用文字都函括进去。
它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。
但自从unicode2.0开始,unicode采用了与ISO 10646-1相同的字库和字码,ISO也承诺ISO10646将不会给超出0x10FFFF的UCS-4编码赋值,使得两者保持一致。
Unicode的编码方式与ISO 10646的通用字符集(Universal Character Set,UCS)概念相对应,目前的用于实用的Unicode版本对应于UCS-2,使用16位的编码空间。
也就是每个字符占用2个字节,基本满足各种语言的使用。实际上目前版本的Unicode尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。

UTF:
Unicode 的实现方式不同于编码方式。
一个字符的Unicode编码是确定的,但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。
Unicode的实现方式称为Unicode转换格式(Unicode Translation Format,简称为 UTF)。
    * UTF-8: 8bit变长编码,对于大多数常用字符集(ASCII中0~127字符)它只使用单字节,而对其它常用字符(特别是朝鲜和汉语会意文字),它使用3字节。
    * UTF-16: 16bit编码,是变长码,大致相当于20位编码,值在0到0x10FFFF之间,基本上就是unicode编码的实现,与CPU字序有关。


汉字编码:
    * GB2312字集是简体字集,全称为GB2312(80)字集,共包括国标简体汉字6763个。
    * BIG5字集是台湾繁体字集,共包括国标繁体汉字13053个。
    * GBK字集是简繁字集,包括了GB字集、BIG5字集和一些符号,共包括21003个字符。
    * GB18030是国家制定的一个强制性大字集标准,全称为GB18030-2000,它的推出使汉字集有了一个“大一统”的标准。

ANSI和Unicode big endia:
我们在Windows系统中保存文本文件时通常可以选择编码为ANSI、Unicode、Unicode big endian和UTF-8,这里的ANSI和Unicode big endia是什么编码呢?
ANSI:
使用2个字节来代表一个字符的各种汉字延伸编码方式,称为ANSI编码。
在简体中文系统下,ANSI编码代表GB2312编码,在日文操作系统下,ANSI编码代表JIS编码。
Unicode big endia:
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。
Unicode规范中推荐的标记字节顺序的方法是BOM(即Byte Order Mark)。
在UCS编码中有一个叫做ZERO WIDTH NO-BREAK SPACE的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。
UCS规范建议我们在传输字节流前,先传输字符ZERO WIDTH NO-BREAK SPACE。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。
因此字符ZERO WIDTH NO-BREAK SPACE又被称作BOM。
Windows就是使用BOM来标记文本文件的编码方式的。

三、编程语言与编码

C、C++、Python2内部字符串都是使用当前系统默认编码
Python3、Java内部字符串用Unicode保存
Ruby有一个内部变量$KCODE用来表示可识别的多字节字符串的编码,变量值为EUC SJIS UTF8 NONE之一。
$KCODE的值为EUC时,将假定字符串或正则表达式的编码为EUC-JP。
同样地,若为SJIS时则认定为Shift JIS。若为UTF8时则认定为UTF-8。
若为NONE时,将不会识别多字节字符串。
在向该变量赋值时,只有第1个字节起作用,且不区分大小写字母。
e E 代表 EUC,s S 代表 SJIS,u U 代表 UTF8,而n N 则代表 NONE。
默认值为NONE。
即默认情况下Ruby把字符串当成单字节序列来处理。

四、为什么会乱码?

乱码是个老问题,从上面我们知道,字符在保存时的编码格式如果和要显示的编码格式不一样的话,就会出现乱码问题。
我们的Web系统,从底层数据库编码、Web应用程序编码到HTML页面编码,如果有一项不一致的话,就会出现乱码。
所以,解决乱码问题说难也难说简单也简单,关键是让交互系统之间编码一致。

五、有没有万金油?

在如此多种编码和字符集弄的我们眼花缭乱的情况下,我们只需选择一种兼容性最好的编码方式和字符集,让它成为我们程序子系统之间
交互的编码契约,那么从此恼人的乱码问题即将远离我们而去 -- 这种兼容性最好的编码就是UTF-8!
毕竟GBK/GB2312是国内的标准,当我们大量使用国外的开源软件时,UTF-8才是编码界最通用的语言。
分享到:
评论

相关推荐

    字符集和字符编码详解

    了解字符集和字符编码有助于我们解决各种编码问题,如文件编码转换、网页显示异常等。在开发过程中,我们需要确保数据的输入、存储、传输和显示都使用相同的字符编码,以保证数据的一致性和正确性。同时,理解这些...

    Java字符集和编码

    因此,深入理解Java中的字符集和编码对于解决这些问题至关重要。 #### 二、基础知识 ##### 1. ASCII编码 ASCII编码(American Standard Code for Information Interchange,美国标准信息交换码)是由美国国家标准...

    informix字符集转换

    在深入探讨Informix字符集转换之前,我们首先需要了解什么是字符集。字符集是一种用于表示文本的标准集合,它定义了一组字符及其编码方式。不同的地区和语言可能使用不同的字符集,例如ASCII、UTF-8、GB2312等。 ##...

    Java中的字符集编码入门(二)编码字符集与字符集编码的区别[参考].pdf

    总的来说,字符集编码和字符集编码是文本处理中的核心概念,理解它们的区别有助于我们在编程中有效地处理字符和文本数据。无论是开发Web应用、桌面软件还是移动应用,都需要对字符编码有深入的理解,以便在处理各种...

    mysql字符集转换

    ### MySQL字符集转换详解 ...在实际工作中,合理地选择和使用字符集不仅可以提升数据的一致性和准确性,还能有效解决国际化等问题。希望本文能够帮助读者更好地理解和掌握MySQL字符集转换的方法和技术要点。

    字符集编码

    在互联网和计算机系统中,字符集编码扮演着至关重要的角色,确保了不同语言的文字能被正确地存储、传输和显示。 首先,我们来看看“Gb2312字符集编码”。GB2312,全称“国标汉字编码字符集”,是中国大陆最早制定的...

    Oracle字符集专题

    首先,我们要了解字符集在Oracle数据库中的核心作用。字符集是用来表示和存储字符的规则集合,它定义了字符的编码方式,使得计算机能够识别和处理文本数据。Oracle支持多种字符集,如US7ASCII、WE8ISO8859P1、AL32...

    SQL SERVER 字符集问题之一解决

    在 SQL SERVER 中,字符集问题是一个复杂的问题,需要深入了解字符集的原理和应用。同时,需要了解数据库设计和优化的原则,以便更好地解决数据库问题。 七、参考文献 1. SQL SERVER 官方文档 2. DATABASE DESIGN ...

    深入分析 Java 中的中文编码问题

    在Java中,还可以使用`CharsetEncoder`和`CharsetDecoder`进行自定义的编码和解码操作。这两个类提供了更灵活的控制方式,可以用于处理复杂的情况。 总的来说,解决Java中的中文编码问题,关键在于理解不同编码之间...

    MYSQL修改字符集默认问题

    在深入探讨修改字符集的方法之前,我们首先需要了解MySQL中的字符集概念。字符集是指一系列字符及其编码方式的集合。在MySQL中,常用的字符集有`latin1`、`utf8`等。其中: - **`latin1`**:支持西欧语言,占用一个...

    字符编码转换,支持任意编码

    首先,我们来了解字符编码的基本概念。字符编码是一种将字符与数字对应的方法,使得计算机能够识别和存储文字。最早的字符编码是ASCII,它只包含了128个英文字符。随着全球化的发展,更广泛的字符集如ISO 8859系列和...

    不同字符编码转换

    这里我们将深入探讨标题和描述中提到的一些主要字符编码格式:UTF-8、UTF-7、ASCII、Unicode以及GB2312,同时还会涉及到大五码(Big5)以及它们之间的转换。 1. ASCII编码:ASCII(美国标准信息交换代码)是最基础...

    深入理解字符编码

    深入了解字符编码不仅能帮助我们更有效地处理文本数据,还能避免因编码不一致导致的问题。随着国际化应用的需求日益增长,掌握多种字符集和编码方式变得越来越重要。通过本篇文章的学习,我们可以更好地理解和应对...

    字符编码转换iconv

    通过指定输入编码、输出编码和待转换的文件,`iconv` 可以将文本从一种编码转换为另一种编码。例如,将一个使用 GBK 编码的文本文件转换为 UTF-8 编码,可以使用以下命令: ```bash iconv -f GBK -t UTF-8 input....

    cxf3.2.0编码GBK的不可映射字符问题

    总的来说,解决CXF3.2.0的GBK编码问题需要理解字符编码的工作原理,并对CXF的配置和处理流程有深入的了解。通过上述方法,可以有效地避免和处理这种不可映射字符的错误,保证服务的正常运行和数据的准确传输。在实际...

    GB2312汉字编码字符集1

    此外,GB2312编码还广泛应用于中文字符集的转换过程中,例如在将GB2312编码转换为Unicode编码时,了解GB2312的原理是十分必要的。 回顾GB2312汉字编码字符集,我们不禁感叹科技力量的神奇。它从本质上改变了信息...

    字符串编码简介和编码转换

    在国际化的背景下,字符串编码显得尤为重要,因为不同的语言和文化可能使用不同的字符集,这就需要有标准来统一处理这些差异。 首先,让我们了解一下什么是字符编码。字符编码是一种规则,它将字符(如字母、数字、...

    中文字符编码(ChineseCharacterCodes).zip

    这个压缩包“中文字符编码(ChineseCharacterCodes).zip”包含了五种主要的中文字符集,分别是Unicode、GB2312-80、GBK、Big 5和CNS。这些字符集在不同的历史时期和应用场景下扮演了关键角色,对于理解中文信息处理和...

Global site tag (gtag.js) - Google Analytics