`
winzenghua
  • 浏览: 1327590 次
  • 性别: Icon_minigender_2
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

计算机编码的基本知识

阅读更多


关键字:Unicode,CharacterSet,字符集,UTF-8,ANSI,ASCII,UTF-7
原文标题:TheAbsoluteMinimumEverySoftwareDeveloperAbsolutely,PositivelyMustKnow
AboutUnicodeandCharacterSets(NoExcuses!)
原文链接:::URL::http://www.joelonsoftware.com/printerFriendly/articles/Unicode.html
作者:JoelSpolsky
翻译、摘要:木野狐(ChenRong2003[at]hotmail.com)
日期:2004-11-29



ASCII码
------------------------------------------------------------------------------------
7位(00~7F)。32~127表示字符。32是空格,32以下是控制字符(不可见)。
第8位没有被使用。全世界很多人同时对这个位的含义发展了不同的用处。比如IBMPC中的OEM字符集。
最后就128位以下的用处达成共识,制定了ASCII标准。
而128位以上的可能有不同的解释,这些不同的解释就叫做codepages.
甚至有用于在同一台电脑上解释多种语言的codepage.

同时,在亚洲发生了更加疯狂的事情。亚洲语言的字符集通常数以千计,8位已经不足以表达,这通常用一种
很凌乱的,叫做DBCS(双字节字符集,doublebytecharacterset)的系统来解决。
这种系统中,有些字符占用1字节,有些2字节。这样一来,在字符串中向前解析很容易,而倒退却很麻烦。
程序员们被建议,不要使用s++或s--来前进和后退,而使用一些函数,比如Windows的AnsiNext和
AnsiPrev.因为这些函数知道是怎么回事。

这些不同的假设(codepage)在单个的机器上没有问题。而随着Internet的发展,字符串要从一个机器上移到
另一个机器上,这就产生了问题。于是,Unicode出现了。

Unicode
---------------------------------------------------------------------------------------
Unicode是一个勇敢的成就。它把在这个星球上的每一个合理的文字系统整合成了一个单一的字符集。
很多人还存在这样的误解:Unicode仅仅是16位的这么简单,每个字符占16位,所以一共有65536个可能的字符。
然而,这是错误的。不过不要紧,因为这是大部分人都会犯的一个普遍的错误。

实际上,Unicode理解字符的方式是截然不同的,而这是我们必须了解的。
到目前为止,我们都曾经认为:一个字符对应到一些在磁盘上或内存中储存的位(bits).如:A->01000001
而在Unicode中,一个字符实际上对应一种叫做codepoint的东西。
比如A这个字符,是抽象的(原文:platonic,柏拉图式的,理想的)一个概念。
无论是TimesNewRoman或者Helvetica或者其他的什么字体中,都代表同一个字符。但是它和小写的字母a不同。
但是在其他的语言,比如希伯莱语(Hebrew)或者德语(German),阿拉伯语(Arabian)中,同一个字母的不同的字形代表的含义是否
相同,是有争议的。经过长时间的争论,这些也终于被确定了。

每一个字母表中的每一个抽象的字母,都被赋予了一个数字,比如U+0645.这个叫做codepoint.
U+表示:Unicode,数字是16进制的。
你可以通过charmap命令来查看所有这些编码。(Windows2000/XP中).或者访问Unicode的网站(::URL::http://www.unicode.org)
Unicode中codepoint的数字的大小是没有限制的,而且也早就超过了65535.所以不是每个字符都能存储在两个字节中。
那么,一个字符串"Hello",在Unicode中会表示成5个codepoints:
U+0048U+0065U+006CU+006CU+006F
只不过是一些数字。但我们现在还没有提到如何在磁盘或者Email中表示这些信息,这就是我们下面要提到的编码(Encoding)干的事情。

Encodings(编码)
-------------------------------------------------------------------------
最初的UnicodeEncoding,使用两个字节表示一个字符。那么"Hello"表示为:
00480065006C006C006F
实际上,还有一种表示方式:
480065006C006C006F00
到底高位字节在前还是低位字节在前面,是两种不同的模式。这要看特定的CPU在何种模式下工作的更快。所以这两种都有。
这就有了两种不同的Unicode表示方式了,为了区分,人们又采用了一种奇异的方式:
在每一个Unicode字符串的前面,加上FEFF(这称为Unicode字节顺序标志,UnicodeByteOrderMark).
如果你交换高位和低位次序,那么会加上一个FFFE.这样,读这个字符串的人才知道要对每两个相邻的字节进行交换。
但在最初的时候,并不是每一个Unicode字符串都有这个标志的。

这看起来很不错。可程序员们开始抱怨了,“看看那些零!”。因为有些是美国人,他们使用英语。而英语中很少需要使用U+00FF以上的
字符,有些人无法忍受采用双倍的存储空间来存储每个字符。
基于这些原因,很多人决定忽视Unicode,而同时,事情变得更糟了。

然后人们制定了UTF-8.UTF-8是用于保存Unicodecodepoints的另一套系统。
每一个U+数字,在内存中占用8bit.在UTF-8中,任何一个0~127的codepoint占用一个字节。
只有128以及更大的才占用2,3,直到6个字节。
具体如下图所示:

16进制的最小的数16进制的最大的数内存中的字节序列
------------------------------------------------------------------------------
000000000000007F0vvvvvvv
00000080000007FF110vvvvv10vvvvvv
000008000000FFFF1110vvvv10vvvvvv10vvvvvv
00010000001FFFFF11110vvv10vvvvvv10vvvvvv10vvvvvv
0020000003FFFFFF111110vv10vvvvvv10vvvvvv10vvvvvv10vvvvvv
040000007FFFFFFF1111110v10vvvvvv10vvvvvv10vvvvvv10vvvvvv10vvvvvv

这看起来很不错,其中的英文字符和ASCII中一样。所以美国人根本没意识到有什么错误。只有世界上的其他国家需要使用高位的字节。
特别的,"Hello"这个字符串,Unicodecodepoint为U+0048U+0065U+006CU+006CU+006F,会被存储为48656C6C6F。
和ASCII,ANSI,以及在这个星球上的任何一个OEM的字符集中表示的含义都一样。
现在,如果你需要表示重音的字符,或者希腊语,你需要使用多个字节来表示一个codepoint.但美国人不会介意这些。
(UTF-8还有一个好处就是,老的字符串处理程序使用一个为0的字节来表示null-terminator,不会截断字符串)

到目前为止已经介绍了三种Unicode的表示方法:

传统的双字节表示方法,称为UCS-2(因为有2个字节)或者UTF-16(因为有16个位)
而且你还要搞清楚是高位在前的,还是高位在后的UCS-2.

还有一种就是新的UTF-8.如果你的程序只使用英文的话,它仍然会工作正常。

实际上还有一堆的其他办法对Unicode进行编码:
UTF-7,这种编码方式大部分和UTF-8相同,但保证高位一定为0.
所以如果你必须通过某种Email系统传送Unicode,这些系统认为7位足够了,那使用UTF-7会正常。
还有UCS-4,储存每一个codepoint为4个字节。它的优点是每一个字符都保存为同样长的。但很明显,缺点是浪费太多存储空间了。

所以,现在你思考问题要把每一个字符想象成抽象的一个unicodecodepoint.而它们同样可以使用任何旧的方式编码。
举例来说,你可以把Unicode字符串Hello(U+0048U+0065U+006CU+006CU+006F)编码(encode)为
ASCII,或者古老的OEM希腊语编码,或者希柏莱ANSI编码,等等。而有些字符串不能显示!
也就是说,假如你要表示一个在某个编码中没有对应的Unicodecodepoint,通常会显示为一个?或者一个白色的小方框。

英文常用的一些编码有,Windows-1252(Windows9x标准for西欧语言)
以及ISO-8859-1,akaLatin-1(对任何西欧语言也有效)
如果用这些编码来尝试存储俄文字符,你会得到一堆的?

UTF7,8,16以及32都有一个优点,能够正确的存储任何的codepoint.

最简单,也是最重要的几个概念
====================================================================
一个字符串不指定它使用什么编码是没有意义的。
再也不要假定,“纯”文本(plaintext)是ASCII.
没有“纯文本”这个东西。

如果你有一个字符串,在内存中,在文件中,或者在Email消息里,你必须知道它的编码是什么。否则你无法正确的解释或者显示给用户。
所有的诸如“我的网页不能正常显示了”,或者”Email消息不能正常显示了“之类的愚蠢问题,都是因为,没有告诉你到底是使用的那种编码,
UTF-8还是ASCII还是ISO8859-1或者Windows1252??那么自然无法正常的解释和显示,甚至不知道字符串该在哪里结束。

那么如何保留这样的编码标志,来表示字符串的编码?有一些基本的办法。
比如对于Email来说,在表单的header中加上:

Content-Type:text/plain;charset="UTF-8"

对于Web页面来说,原来的做法是,Web服务器随着web页面本身一起,发送一个类似于Content-Type的httpheader.
(不是在HTML里面,而是作为一个responseheader在HTML页之前发送)

这样做有一个问题。如果你的Web服务器同时有多个站点,站点由多个不同的人用不同的语言开发的程序混在一起。那么Web服务器将无从得知,
每一个文件是用什么编码方式写的。这样也就无法发送正确的Content-Typeheader.
如果你能够在每一个HTML文件中记录Content-Type信息,那么就很方便了。可这念头似乎也很疯狂,因为你还没有知道用什么编码方式去
读取这个文件,又怎么能读出编码信息呢?
幸好,几乎每一种编码中,对32~127的字符都解释的相同。所以你可以在每一个html文件中这么写:



<metahttp-equiv="Content-Type"content="text/html;charset=utf-8">

但是要注意,这个meta标签必须放在head中靠前面的位置才能保证不会出问题。因为Web服务器读到这里的时候,就会停止解析,
然后用读到的这个编码方式重新解析页面。

那么,作为Web浏览器来说,如果没有在meta标签中或者httpheaders中发现Content-Type,会怎么样呢?
IE是这么做的:
先尝试去猜,根据特定的字节出现在各种语言的典型的编码中的频率。
如果编码设定不正常,用户可以通过View|Encoding菜单来尝试不同的编码方式。(当然,不是每个人都知道该这样做)

在VB,COM,WindowsNT/2000/XP中,默认的字符串类型是UCS-2(2字节)的。
在C++代码中,我们可以定义字符串为wchar_t(widechar),同时用wcs系列的函数代替str系列的函数。
如wcscat,wcslen,而不是strcat,strlen.
在C代码中,要创建UCS-2字符串的话,只要在前面加一个"L",如L"Hello"

对于Web页面,最好统一为使用UTF-8编码。这个编码已经被各种web浏览器支持了很多年了。

关于UTF介绍的页面http://czyborra.com/utf/#UTF-1
分享到:
评论

相关推荐

    计算机应用基础知识(共59张PPT).pptx

    目录 计算机概述 数制与编码 计算机中字符的编码 指令和程序设计语言 计算机系统的组成 微型计算机的硬件系统 多媒体技术简介 计算机病毒及其防治 计算机应用基础知识(共59张PPT)全文共59页,当前为第2页。...

    计算机基础知识-编码表.doc

    计算机基础知识-编码表 模块:计算机基础知识 主题:编码表 关键词:ASCII、Unicode、UTF-8 1、编码表 计算机发明之初,用来解决数字计算的问题,后来人们发现可以做更多的事,但由 于计算机只识" 数",因此人们必须...

    计算机应用基础第二章-计算机基础知识.docx

    计算机应用基础第二章-计算机基础知识全文共6页,当前为第1页。计算机应用基础第二章-计算机基础知识全文共6页,当前为第1页。第二章 计算机基础知识 计算机应用基础第二章-计算机基础知识全文共6页,当前为第1页。 ...

    计算机应用基础第二章-计算机基础知识(1).docx

    计算机应用基础第二章-计算机基础知识(1)全文共6页,当前为第1页。计算机应用基础第二章-计算机基础知识(1)全文共6页,当前为第1页。第二章 计算机基础知识 计算机应用基础第二章-计算机基础知识(1)全文共6页,当前...

    2022全国计算机应用基础知识:汉字、字符编码.docx

    2022全国计算机应用基础知识:汉字、字符编码.docx

    计算机基础知识

    计算机基础知识:关于数值和编码的转换问题

    计算机硬件基础知识

    信息编码于数据表示,微型计算机系统的组成,计算机数据的安全

    计算机基础教材,包括计算机的软硬件基础知识、计算机的工作原理和机内信息编码

    计算机基础教材,包括计算机的软硬件基础知识、计算机的工作原理和机内信息编码。

    全国计算机应用基础知识:汉字、字符编码.pdf

    全国计算机应⽤基础知识:汉字、字符编码 (1)计算机中的信息单位 计算机中对信息表⽰的单位有位、字、字长及字节等,它们是⽤来表⽰信息量的⼤⼩的基本概念。 位:计算机中数据存储的最⼩单位是⼀个⼆进制位,简称...

    计算机应用基础知识概述.doc

    第1章 计算机应用基础知识概述 第3讲 计算机应用基础知识概述(三) 教学目标及基本要求: 1、掌握计算机中的数制与转换。 2、了解计算机中信息的表示与编码 。 教学重点: 二进制(Binary)的特点。 1. 教学难点: 二...

    《计算机应用基础》计算机基础知识二.docx

    《计算机应用基础》计算机基础知识二 《计算机应用基础》计算机基础知识二全文共13页,当前为第1页。《计算机应用基础》计算机基础知识二全文共13页,当前为第1页。一、数据与信息 《计算机应用基础》计算机基础知识...

    编码的奥秘(真正理解计算机的组成原理和工作过程)

    要学习计算机的基础知识,真正理解计算机的组成原理和工作过程往往是一件令人头痛的事,即使对计算机专业的学生来说,也并不轻松。 本书无疑将会成为你的好朋友。随着作者的思路,你将轻松自如地了解到计算机软件...

    计算机的基础知识.pptx

    第一节 数制与编码 第二节 计算机的基本组成电路 第三节 存储器 第二章 计算机基础知识 返回总目录 计算机的基础知识全文共36页,当前为第1页。 第2章 计算机基础知识 教学目的:了解计算机中所用数制码制,计算机的...

    计算机应用基础知识总结大全精编.docx

    计算机应用基础知识总结大全精编 Document number:WTT-LKK-GBB-08921-EIGG-22986 Document number:WTT-LKK-GBB-08921-EIGG-22986 计算机应用基础知识总结大全精编全文共34页,当前为第1页。计算机应用基础知识总结...

    计算机基础与C语言程序设计(第三版)第1章-计算机基础知识.pptx

    第1章 计算机基础知识 1.1 计算机系统与工作原理 1.2 数制与编码 1.3 PC的基本配置及性能指标 计算机基础与C语言程序设计(第三版)第1章-计算机基础知识全文共98页,当前为第2页。 1.1计算机系统与工作原理 1.1.1 ...

    计算机应用基础课程辅导-计算机基础知识.doc

    广播电视大学开放专科 《计算机应用基础》教学辅导1 基础知识内容包括:计算机基本知识、计算机信息处理技术。 重点理解和掌握的内容 1. 了解计算机发展简史及现代计算机的发展和应用领域; 2. 了解计算机的定义与...

    自考计算机应用基础知识点.docx

    自考计算机应用基础知识点 1 自考计算机应用基础知识点全文共16页,当前为第1页。自考计算机应用基础知识点全文共16页,当前为第1页。计算机基础知识点 自考计算机应用基础知识点全文共16页,当前为第1页。 自考...

    1计算机应用基础.pptx

    1 计算机基础知识 1.2 计算机系统组成及工作原理 1.4 计算机病毒与防护 1.1 计算机概述 1.3 数据在计算机中表示与编码 课后习题 1计算机应用基础全文共58页,当前为第4页。 1.1 计算机概述 1 计算机基础知识 1.1.1 ...

    AB计算机基础知识——计算机基础知识资料文档.doc

    计算机基础知识 按电子计算机传统的分代方法,第一代至第四代计算机依次是______。 A、机械计算机,电子管计算机,晶体管计算机,集成电路计算机 B、晶体管计算机,集成电路计算机,大规模集成电路计算机,光器件...

    计算机应用基础(Win7+Office2016)全套教案.docx

    学习领域 计算机应用基础 总 课 时 32学时 学习情境1 计算机基础知识 情 境 课 时 2学时 学 习 目 标 教 学 案 例 认识计算机的发展 了解计算机中信息的表示和存储 认识多媒体技术 认识计算机的硬件系统 认识计算机...

Global site tag (gtag.js) - Google Analytics