心得经验总结:浅谈文字编码和unicode(下)

简介: 心得经验总结:浅谈文字编码和unicode(下)

浅谈文字编码和Unicode(下)

3 字符编码模型

程序员经常会面对复杂的问题,而降低复杂性的最简单的方法就是分而治之。Peter Constable在他的文章"Character set encoding basics Understanding character set encodings and legacy encodings"中描述了字符编码的四层模型。我觉得这种说法确实可以更清晰地展现字符编码中发生的事情,所以在这里也介绍一下。

3.1 字符的范围(Abstract character repertoire)

设计字符编码的第一层就是确定字符的范围,即要支持哪些字符。有些编码方案的字符范围是固定的,例如ASCII、ISO 8859 系列。有些编码方案的字符范围是开放的,例如Unicode的字符范围就是世界上所有的字符。

3.2 用数字表示字符(Coded character set)

设计字符编码的第二层是将字符和数字对应起来。可以将这个层次理解成数学家(即从数学角度)看到的字符编码。数学家看到的字符编码是一个正整数。例如在Unicode中:汉字“字”对应的数字是23383。汉字“”对应的数字是134192。

在写html文件时,可以通过输入"字"来插入字符“字”。不过在设计字符编码时,我们还是习惯用16进制表示数字。即将23383写成0x5BD7,将134192写成0x20C30。

3.3 用基本数据类型表示字符(Character encoding form)

设计字符编码的第三层是用编程语言中的基本数据类型来表示字符。可以将这个层次理解成程序员看到的字符编码。在Unicode中,我们有很多方式将数字23383表示成程序中的数据,包括:UTF-8、UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。例如,“汉字”对应的数字是0x6c49和0x5b57,而编码的程序数据是:

BYTE data_utf8【】={0xE6,0xB1,0x89,0xE5,0xAD,0x97}; // UTF-8编码

WORD data_utf16【】={0x6c49,0x5b57}; // UTF-16编码

DWORD data_utf32【】={0x6c49,0x5b57}; // UTF-32编码

这里用BYTE、WORD、DWORD分别表示无符号8位整数,无符号16位整数和无符号32位整数。UTF-8、UTF-16、UTF-32分别以BYTE、WORD、DWORD作为编码单位。

“汉字”的UTF-8编码需要6个字节。“汉字”的UTF-16编码需要两个WORD,大小是4个字节。“汉字”的UTF-32编码需要两个//代码效果参考:http://www.zidongmutanji.com/zsjx/524915.html

DWORD,大小是8个字节。4.2节会介绍将数字映射到UTF编码的规则。

3.4 作为字节流的字符(Character encoding scheme)

字符编码的第四层是计算机看到的字符,即在文件或内存中的字节流。例如,“字”的UTF-32编码是0x5b57,如果用little endian表示,字节流是“57 5b 00 00”。如果用big endian表示,字节流是“00 00 5b 57”。

字符编码的第三层规定了一个字符由哪些编码单位按什么顺序表示。字符编码的第四层在第三层的基础上又考虑了编码单位内部的字节序。UTF-8的编码单位是字节,不受字节序的影响。UTF-16、UTF-32根据字节序的不同,又衍生出UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BE四种编码方案。LE和BE分别是Little Endian和Big Endian的缩写。

3.5 小结

通过四层模型,我们又把字符编码中发生的这些事情梳理了一遍。其实大多数代码页都不需要完整的四层模型,例如GB18030以字节为编码单位,直接规定了字节序列和字符的映射关系,跳过了第二层,也不需要第四层。

4 再谈Unicode

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

Unicode字符集可以简写为UCS(Unicode Character Set)。早期的Unicode标准有UCS-2、UCS-4的说法。UCS-2用两个字节编码,UCS-4用4个字节编码。UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个平面(plane)。每个平面根据第3个字节分为256行 (row),每行有256个码位(cell)。group 0的平面0被称作BMP(Basic Multilingual Plane)。将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。

Unicode标准计划使用group 0 的17个平面: 从BMP(平面0)到平面16,即数字0-0//代码效果参考:http://www.zidongmutanji.com/bxxx/523598.html

x10FFFF。《谈谈Unicode编码》主要介绍了BMP的编码,本文将介绍完整的Unicode编码,并从多个角度浏览Unicode。本文的介绍基于Unicode 5.0.0版本。

4.1 浏览Unicode

先看一些数字:每个平面有2^16=65536个码位。Unicode计划使用了17个平面,一共有1765536=1114112个码位。其实,现在已定义的码位只有238605个,分布在平面0、平面1、平面2、平面14、平面15、平面16。其中平面15和平面16上只是定义了两个各占65534个码位的专用区(Private Use Area),分别是0xF0000-0xFFFFD和0x100000-0x10FFFD。所谓专用区,就是保留给大家放自定义字符的区域,可以简写为PUA。

平面0也有一个专用区:0xE000-0xF8FF,有6400个码位。平面0的0xD800-0xDFFF,共2048个码位,是一个被称作代理区(Surrogate)的特殊区域。它的用途将在4.2节介绍。

238605-655342-6400-2408=99089。余下的99089个已定义码位分布在平面0、平面1、平面2和平面14上,它们对应着Unicode目前定义的99089个字符,其中包括71226个汉字。平面0、平面1、平面2和平面14上分别定义了52080、3419、43253和337个字符。平面2的43253个字符都是汉字。平面0上定义了27973个汉字。

在更深入地了解Unicode字符前,我们先了解一下UCD。

4.1.1 什么是UCD

UCD是Unicode字符数据库(Unicode Character Database)的缩写。UCD由一些描述Unicode字符属性和内部关系的纯文本或html文件组成。大家可以在Unicode组织的网站看到UCD的最新版本。

UCD中的文本文件大都是适合于程序分析的Unicode相关数据。其中的html文件解释了数据库的组织,数据的格式和含义。UCD中最庞大的文件无疑就是描述汉字属性的文件Unihan.txt。在UCD 5.0,0中,Unihan.txt文件大小有28,221K字节。Unihan.txt中包含了很多有参考价值的索引,例如汉字部首、笔划、拼音、使用频度、四角号码排序等。这些索引都是基于一些比较权威的辞典,但大多数索引只能检索部分汉字。

我介绍UCD的目的主要是为了使用其中的两个概念:Block和Script。

4.1.2 //代码效果参考:http://www.zidongmutanji.com/bxxx/111448.html

Block

UCD中的Blocks.txt将Unicode的码位分割成一些连续的Block,并描述了每个Block的用途:

开始码位

结束码位

Block名称(英文)

Block名称(中文)

0000

007F

Basic Latin

基本拉丁字母

0080

00FF

Latin-1 Supplement

拉丁字母补充-1

0100

017F

Latin Extended-A

拉丁字母扩充-A

0180

024F

Latin Extended-B

拉丁字母扩充-B

0250

02AF

IPA Extensions

国际音标扩充

02B0

02FF

Spacing Modifier Letters

进格修饰字符

0300

036F

Combining Diacritical Marks

组合附加符号

0370

03FF

Greek and Coptic

希腊文和哥普特文

0400

04FF

Cyrillic

西里尔文

0500

052F

Cyrillic Supplement

西里尔文补充

0530

058F

Armenian

亚美尼亚文

0590

05FF

Hebrew

希伯来文

0600

06FF

Arabic

基本阿拉伯文

0700

074F

Syriac

叙利亚文

0750

077F

Arabic Supplement

阿拉伯文补充

0780

07BF

Thaana

塔纳文

07C0

07FF

NKo

N'Ko字母表

0900

097F

Devanagari

天成文书(梵文)

0980

09FF

Bengali

孟加拉文

0A00

0A7F

Gurmukhi

锡克教文

0A80

0AFF

Gujarati

古吉拉特文

0B00

0B7F

Oriya

奥里亚文

0B80

0BFF

Tamil

泰米尔文

0C00

0C7F

Telugu

泰卢固文

0C80

0CFF

Kannada

卡纳达文

0D00

0D7F

Malayalam

德拉维族文

0D80

0DFF

Sinhala

僧伽罗文

0E00

0E7F

Thai

泰文

0E80

0EFF

Lao

老挝文

0F00

0FFF

Tibetan

藏文

1000

109F

Myanmar

缅甸文

10A0

10FF

Georgian

格鲁吉亚文

1100

11FF

Hangul Jamo

朝鲜文

1200

137F

Ethiopic

埃塞俄比亚文

1380

139F

Ethiopic Supplement

埃塞俄比亚文补充

13A0

13FF

Cherokee

切罗基文

1400

167F

Unified Canadian Aboriginal Syllabics

加拿大印第安方言

1680

169F

Ogham

欧甘文

16A0

16FF

Runic

北欧古字

1700

171F

Tagalog

塔加路文

1720

173F

Hanunoo

哈努诺文

1740

175F

Buhid

布迪文

1760

177F

Tagbanwa

Tagbanwa文

1780

17FF

Khmer

高棉文

1800

18AF

Mongolian

蒙古文

1900

194F

Limbu

林布文

1950

197F

Tai Le

德宏傣文

1980

19DF

New Tai Lue

新傣文

19E0

19FF

Khmer Symbols

高棉文

1A00

1A1F

Buginese

布吉文

1B00

1B7F

Balinese

巴厘文

1D00

1D7F

Phonetic Extensions

拉丁字母音标扩充

1D80

1DBF

Phonetic Extensions Supplement

拉丁字母音标扩充增补

1DC0

1DFF

Combining Diacritical Marks Supplement

组合附加符号补充

1E00

1EFF

Latin Extended Additional

拉丁字母扩充附加

1F00

1FFF

Greek Extended

希腊文扩充

2000

206F

General Punctuation

一般标点符号

2070

209F

Superscripts and Subscripts

上标和下标

20A0

20CF

Currency Symbols

货币符号

20D0

20FF

Combining Diacritical Marks for Symbols

符号用组合附加符号

2100

214F

Letterlike Symbols

似字母符号

2150

218F

Number Forms

数字形式

2190

21FF

Arrows

箭头符号

2200

22FF

Mathematical Operators

数学运算符号

2300

23FF

Miscellaneous Technical

零杂技术用符号

2400

243F

Control Pictures

控制图符

2440

245F

Optical Character Recognition

光学字符识别

2460

24FF

Enclosed Alphanumerics

带括号的字母数字

2500

257F

Box Drawing

制表符

2580

259F

Block Elements

方块元素

25A0

25FF

Geometric Shapes

几何形状

2600

26FF

Miscellaneous Symbols

零杂符号

2700

27BF

Dingbats

杂锦字型

27C0

27EF

Miscellaneous Mathematical Symbols-A

零杂数学符号-A

27F0

27FF

Supplemental Arrows-A

箭头符号补充-A

2800

28FF

Braille Patterns

盲文

2900

297F

Supplemental Arrows-B

箭头符号补充-B

2980

29FF

Miscellaneous Mathematical Symbols-B

零杂数学符号-B

2A00

2AFF

Supplemental Mathematical Operators

数学运算符号

2B00

2BFF

Miscellaneous Symbols and Arrows

零杂符号和箭头

2C00

2C5F

Glagolitic

格拉哥里字母表

2C60

2C7F

Latin Extended-C

拉丁字母扩充-C

2C80

2CFF

Coptic

科普特文

2D00

2D2F

Georgian Supplement

格鲁吉亚文补充

2D30

2D7F

Tifinagh

提非纳字母

2D80

2DDF

Ethiopic Extended

埃塞俄比亚文扩充

2E00

2E7F

Supplemental Punctuation

标点符号补充

2E80

2EFF

CJK Radicals Supplement

中日韩部首补充

2F00

2FDF

Kangxi Radicals

康熙字典部首

2FF0

2FFF

Ideographic Description Characters

汉字结构描述字符

3000

303F

CJK Symbols and Punctuation

中日韩符号和标点

3040

309F

Hiragana

平假名

30A0

30FF

Katakana

片假名

3100

312F

Bopomofo

注音符号

3130

318F

Hangul Compatibility Jamo

朝鲜文兼容字母

3190

319F

Kanbun

日文的汉字批注

31A0

31BF

Bopomofo Extended

注音符号扩充

31C0

31EF

CJK Strokes

中日韩笔划

31F0

31FF

Katakana Phonetic Extensions

片假名音标扩充

3200

32FF

Enclosed CJK Letters and Months

带括号的中日韩字母及月份

3300

33FF

CJK Compatibility

中日韩兼容字符

3400

4DBF

CJK Unified Ideographs Extension A

中日韩统一表意文字扩充A

4DC0

4DFF

Yijing Hexagram Symbols

易经六十四卦象

4E00

9FFF

CJK Unified Ideographs

中日韩统一表意文字

A000

A48F

Yi Syllables

彝文音节

A490

A4CF

Yi Radicals

彝文字根

A700

A71F

Modifier Tone Letters

声调修饰字母

A720

A7FF

Latin Extended-D

拉丁字母扩充-D

A800

A82F

Syloti Nagri

Syloti Nagri字母表

A840

A87F

Phags-pa

Phags-pa字母表

AC00<

相关文章
|
2月前
|
存储 自然语言处理 Linux
探究C/C++编码世界:从字符编码到中文处理之艺(三)
探究C/C++编码世界:从字符编码到中文处理之艺
71 2
|
2月前
|
自然语言处理 C++
探究C/C++编码世界:从字符编码到中文处理之艺(二)
探究C/C++编码世界:从字符编码到中文处理之艺
65 2
|
2月前
|
存储 自然语言处理 程序员
探究C/C++编码世界:从字符编码到中文处理之艺(一)
探究C/C++编码世界:从字符编码到中文处理之艺
51 1
|
2月前
|
Linux 编译器 C语言
Linux应用开发基础知识——字符文字编码(五)
Linux应用开发基础知识——字符文字编码(五)
79 0
Linux应用开发基础知识——字符文字编码(五)
|
3天前
|
自然语言处理 程序员 数据库
心得经验总结:浅谈文字编码和unicode(下)
心得经验总结:浅谈文字编码和unicode(下)
|
12月前
|
存储 Windows
“浅入深处“编码历史,字符串编码(ASCII, GBK, ANSI, Unicode, UTF-8编码),为什么记事本默认ANSI编码,Unicode和UTF8有什么区别
“浅入深处“编码历史,字符串编码(ASCII, GBK, ANSI, Unicode, UTF-8编码),为什么记事本默认ANSI编码,Unicode和UTF8有什么区别
100 0
带你读《全景揭秘字符编码》之七:七、常见字符编码1:ASCII
带你读《全景揭秘字符编码》之七:七、常见字符编码1:ASCII
145 0
|
存储 编解码
带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(1)
带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(1)
156 0
带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(10)
带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(10)
|
存储
带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(8)
带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(8)
148 0