在计算机世界中,最经常遇到的字符集是ASCII(American standard code II),这个字符集中定义了英文26个字母和一些常用符号(阿拉伯数字和常用标点等)对应的二进制编码。ASCII码对应的范围是从0x00到0x7f。
ASCII码所能表示的字符一共是128个(包括控制字符),占一个字节,但最高位总是0。对于非英语的国家来说,这些字符是不够的,比如欧洲其它国家,有的字母有重音符号,有的字母与英语字母不一样(像数字中常用的拉丁字母)。于是,他们分别扩展了ASCII码的最高位,因此可以表示256个字符。这些编码都不是统一的,虽然低位的128(0到127)个字符总是和ASCII保持一致,但高位的128(128到255)个字符就各有侧重了。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。
比起亚洲来说,欧洲这样的字母文字地区的编码问题还不算严重。亚洲很多国家都是符号文字(像中国的汉字,日文的假名,非汉字韩文等),这些符号成千上万。一个字节用来表达这些字符是远远不够的,ASCII以及扩展都满足不过这些国家和地区的要求。所以各个国家和地区又纷纷组织编辑了适合于自己字符编码集,比如常见的有中国的GB码,日本的JIS等等。这些编码集都至少用到了2个字节以上来表示自己的文字符号。
Unicode
这些编码集合虽然局部地解决了一些问题,但是又带来了新的问题,那就是,他们都不是统一的(统一的标准只有ASCII码),当各种编码文件之间进行交流的时候,就会产生问题。这非常不利于信息的交流和传递。遇着问题越来越频率地发生,人们对于统一的编码的渴望也就越来越强烈,于是,UNICODE就横空出世了,它满足了人们的两个主要要求:
每个需要表示的字符,都要在unicode中有自己的"位置"。
每个字符都有独立的统一的编码。
Unicode的历史可以追溯到1987年,当时Xerox的Joe Becker和Apple公司的Lee Collins、Mark Davis几个人就开始进行投入到创造一种通用字符集的工作中去了,次年的8月,Joe Backer发表了第一份名为Unicode 88的草案,拉开了unicode发展的序幕。当时这份草案是基于16bit的模型,把所有字符都使用16个bit来表示,因为他们认为,在现代社会中仍在广泛使用的字符个数远远少于16384(2的14次方)个,用16位表示已经足够了。但unicode后来的发展远远超出了这个泛围,许许多少古老的、罕用的或废弃的字符被源源不断地加入到unicode标准中。
最新的unicode(5.0)已经定义了多达1,114,112个字符代码点(code points),编码范围从0到0x10ffff。这些code points被划分成17个字符平面(planes),每个平面包含65536个code points(256行 X 256列)。 如下表:
各平面的字符编码范围:
Plane
|
Range
|
Description
|
Abbreviation
|
0
|
0000-FFFF
|
Basic Multilingual Plane
|
BMP
|
1
|
10000-1FFFF
|
Supplementary Multilingual Plane
|
SMP
|
2
|
20000-2FFFF
|
Supplementary Ideographic Plane
|
SIP
|
3 to 13
|
30000-DFFFF
|
currently unassigned
|
|
14
|
E0000-EFFFF
|
Supplementary Special-purpose Plane
|
SSP
|
15
|
F0000-FFFFF
|
Supplementary Private Use Area-A
|
|
16
|
100000-10FFFF
|
Supplementary Private Use Area-B
|
|
Unicode只是定义了每个字符对应编码,其它的一概不管。比如,汉字"李"的unicode是十六进制数4E67,它是唯一的。对于各种系统和各种应用来说,知道一个unicode编码,就能确定一个字符,但对于字符的其它信息(字体,大小等),unicode就管不着了。
Unicode只是实现了统一编码的愿望,具体应用到实践中,还存在几个问题,比如,如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?还有,我们已经知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有两到三个字节是0,这对于存储来说是极大的浪费,英文文本文件的大小会因此大出二三倍,这是无法接受的。而且,对于现存有很多代码(比如C的标准库)都是以单字节的ASCII码为基础编写的,unicode中很多字符的编码中都有0x00,那么这些已存的代码,处理unicode就不再适合。这些问题都影响着unicode的推广。
从上面知道,除了unicode本身之外,我们还需要定义一些好的存储方案,使得实践中遇到的问题都能得到解决,能与现有的代码和处理系统的存储、处理兼容,又能与unicode兼容的方式,这样就最好了。目前,已经有很多种方案存在了,主要的有unicode Transformation(简称UTF)和Universal Character Set(简称UCS)。采用什么样的方案,取决于应用领域的具体情况(比如合适的存储空间、源代码的兼容性、以及各系统之间的相互操作等)。
在具体介绍某个方案前,我们需要明确的是这些方案与unicode的关系:
这些方案是unicode的具体实现形式,在该方案下,每个字符的存储要能和unicode的定义保持一一映射的关系(在下面UFT8的例子中我们可以看到)。在这个基础上,每种方案可以采用一些自己的规定来解决实践中遇到的各种问题。
下面简单介绍一下常遇到的unicode编码方案:
UTF8是最为常用的unicode字符编码之一,它是一种变长的编码方式,使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于unicode的起启的128个字符,UTF-8编码和ASCII码是完全一致的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。其它的二进制位,全部用于存储符号的unicode码。
UTF-8与Unicode的编码范围之间的关系如下表:
另一种常用的是UCS-2编码方式,很多时候,在遇到直接说unicode编码而不是UFT-N等的具体名称的时候,指的就是UCS-2这种编码,即直接用两个字节存入字符的Unicode码。UCS-2分little endian和bit endian。下面会进行简单的介绍。
Little endian和Big endian
Unicode码可以采用UCS-2格式直接存储。以汉字"李"为例,Unicode码是U+4E67,需要用两个字节存储,一个字节是4E,另一个字节是67。存储的时候,4E在前,67在后,就是Big endian方式;67在前,4E在后,就是Little endian方式。
这两个名称来自英国作家斯威夫特的《格列佛游记》。在该书中,小人国里爆发了内战,战争起因是人们争论吃鸡蛋时究竟是从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。因此,第一个字节在前,就是"大头方式"(Big endian),第二个字节在前就是"小头方式"(Little endian)。
那么很自然的,就会出现一个问题:计算机怎么知道某一个文件到底采用哪一种方式编码?
Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。很多文体编辑器都提供了这两种保存方式,有兴趣可以分别保存之后,用16进制编辑器查开文件的开头,就能进行验证了。
分享到:
相关推荐
#### 编码知识概览 在探讨编码知识时,我们首先需要理解文本和字符的基本概念。在计算机领域,文本是以数字序列的形式存储的,这些数字代表了字符集中的各个字符。字符集定义了哪些字符可用以及如何通过整数(即码...
#### 一、中文Unicode编码概览 **Unicode**是一种国际化的字符编码标准,旨在统一所有书写系统中的字符编码。它不仅涵盖了世界上大多数语言的文字,还包括了符号、表情符号等非文字字符。对于中文而言,Unicode编码...
#### 键盘按键编码概览 - **AA(大写A)**:对应Unicode编码为65。 - **Add**:这是一个特殊功能键,编码为107,用于添加操作。 - **Alt**:Alt键具有两个编码,一个是常规的ALT键(编码262144),另一个是自然键盘...
3. **缩略图预览**:软件可能提供缩略图视图,方便用户在不打开每个文件的情况下概览整个文件夹中的图片。 4. **图像编辑功能**:除了查看,Imagine 可能还包含基本的编辑工具,如裁剪、旋转、调整亮度/对比度、...
下面是一个基本的日志记录类的概览,它支持多字节字符集(MBCS)和Unicode编码: ```cpp // FD_log.h #ifndef FD_LOG_H #define FD_LOG_H #include #include #include #include class FDLog { public: FDLog...
#### UCS-2规范概览 UCS-2规范采用两个字节(即16位)来编码每一个字符。这意呸着它可以表示从`0x0000`到`0xFFFF`之间的65536个不同的字符。这种编码方式在早期的Unicode版本中被广泛使用,因为大多数常见的字符集...
- **Unicode支持**:增强了对Unicode字符串的支持,使程序更易于处理多语言环境。 4. **ATL(Active Template Library)**: - **COM编程**:简化了COM组件的创建,提升了性能和兼容性。 - **ATL服务器和客户端...
LASALSCREEN是一款用于设计人机界面的工具,支持Unicode文字、配方管理、实时图形、趋势图和警报管理。LASALMOTION则将驱动技术融入到工程项目开发工具中,成为项目的一个有机组成部分。LASALSERVICE则用于远程维护...
最后,"字符编码ASCII,Unicode和UTF-8详解.mht"这篇文档会提供一个全面的编码系统概览,特别是对ASCII、Unicode和UTF-8的详细解析。ASCII是最基础的7位字符集,主要覆盖了英文和其他西欧语言的基本字符。Unicode是...
#### 一、文件概览 文件名为“CodeCharts.pdf”,根据描述,这是一份关于UTF-8编码标准的最新版本文档,具体为Unicode标准第13.0版的字符编码表。此文档提供了完整的字符表及字符名称列表。 #### 二、UTF-8编码简介...
#### 内容概览 本文将深入探讨Visual Basic 6.0(简称VB6)中有关内码转换的功能及其应用方法。内码转换是编程领域中一项非常重要的技术,尤其是在处理多种字符编码的环境中。本文将以VB6为例,详细介绍如何利用其...
Django 中的 Unicode Django开源项目 了解 Django 项目本身的开发进程以及您如何为 Django 做贡献: 社区: 如何参与其中 | 发布进程 | 团队组织 | Django 源代码仓库 | 安全政策 | 邮件列表 设计哲学: 概览 文档...
- **与Unicode和ICU字符串类型的集成**:这部分介绍了如何将Boost.Regex与Unicode和ICU字符串类型进行集成,以支持更广泛的字符集和语言环境。 - **与MFC字符串类型的集成**:这部分提供了如何将Boost.Regex与MFC...
### Boost.Regex 帮助文档知识点概览 #### 一、配置与编译设置(Configuration & Compiler Setup) - **配置**:这部分介绍了如何配置Boost.Regex库来满足不同的需求,比如选择支持特定的字符集或者调整算法行为。...
#### 一、汉字编码概览 汉字编码是指将汉字转换为计算机可处理的数字代码的过程。随着信息技术的发展,汉字编码标准也经历了从繁杂到统一的过程。早期的编码系统如GB2312、GBK、GB18030等,分别适用于不同的场合和...