[转] 汉字字符编码的科普笔记

GB2312cp936
 
1. GB2312 简介
GB2312 GB2312-80 ,诞生于 1981 年,共收录 6763 个汉字,其中一级汉字 3755 个,二级汉字 3008 个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的 682 个字符,共 7445 个字符。 GB2312 的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆 99.75% 的使用频率。用区位码表示。范围:区( 01-87 ),位( 01-94 )。
 
2. Code Page
Windows 中使用 VIM 打开一个以 GB2312 方式编码的文档时, file encoding 显示的是“ cp936 ”。在 Windows 中, code page 指的就是字符集,在其他操作系统中称为字符编码( character encodings ),两者是同一概念。 code pages 80 90 年代的 Windows 操作系统中使用,当 Windows 实现了 Unicode 时, code pages 就逐渐被取代。 Code Page 这个词来源于 IBM 的基于 EBCDIC mainframe 系统,但包括微软、 SAP Oracle 在内的很多制造商都使用这个说法。
另一个很奇怪的事情是,同样一份以 GB2312 编码的文档,在 Windows 里用 VIM 打开,就显示为 cp936 编码;在 Linux 里打开时却显示为 utf-8 编码,而不是“ cp936 ”的 unix 说法“ euc-cn ”!但是以十六进制方式查看,发现文字确实是以 GB2312 编码的。可能是 vimrc 里不知道哪儿写错了。具体情况请见 VIM 的帮助文档“ :h encoding-values ”。
 
3. GB2312 的编码
每个汉字及符号以两个字节来表示,高位字节使用了 0xA1-0xF7 ;低位字节使用了 0xA1-0xFE 由于一级汉字从 16 区起始,汉字区的“高位字节”的范围是 0xB0-0xF7 ,“低位字节”的范围是 0xA1-0xFE
Unicode 出现后, GB2312 的全部 7445 个字符都在 Unicode 的覆盖范围之内,并分布在 U+00A4 U+FFE5 之间。另外, GB2312 的常用汉字按拼音排列,次常用汉字按笔画排列,因此与 Unicode 的汉字部分的字序是不同的。
 
GBKChinese Internal Code Specification
 
1. 简介
GBK 诞生于 1993 年的 Unicode 1.1 版之后。之前的 GB2312-80 只有 6763 个汉字,且很多汉字在 1981 年之后才得到简化,故中国大陆制定了等同于 Unicode 1.1 版的“ GB 13000.1-93 ”,收录中国大陆、台湾、日本、韩国的通用字符集,共 20902 个汉字。微软利用 GB 2312-80 未使用的编码空间,收录 GB 13000.1-93 全部字符制定了 GBK 编码。最早实现于 Windows 95 简体中文版。虽然 GBK 收录 GB 13000.1-93 的全部字符,但编码方式并不相同。以下为 GBK 的双字节编码示意:
  [转] 汉字字符编码的科普笔记_第1张图片
 
2. 编码
字符有一字节和双字节编码, 00-7F 范围内是一位,和 ASCII 保持一致,此范围内严格上说有 96 个文字和 32 个控制符号。双字节中,第一字节的范围是 81-FE (也就是不含 80 FF ),第二字节的一部分领域在 40-FE ,其他领域在 80-FE
 
 
GB18030
 
1. 简介
最新版本为 GB 18030-2005 ,与 GB 2312-1980 完全兼容,与 GBK 基本兼容,支持 GB 13000 Unicode 的全部统一汉字,共收录汉字 70244 个。与 UTF-8 相同,采用多字节编码,每个字可以由 1 个、 2 个或 4 个字节组成。支持中国国内少数民族的文字,收录范围包含繁体汉字以及日韩汉字。
 
2. 编码
单字节部分,收录了 GB/T 11383-1989 0x00 0x7F 全部 128 个字符;双字节部分: GB 13000.1-1993 的全部 CJK 统一汉字字符等,其首字节码位从 0x81 0xFE ,尾字节码位分别是 0x40 0x7E 0x80 0xFE 。;四字节部分:收录了上述双字节字符之外的, GB 13000 CJK 统一汉字扩充 A CJK 统一汉字扩充 B 和已经在 GB 13000 中编码的中国少数民族文字的字符,采用 0x30 0x39 作为对双字节编码的扩充的后缀。这样扩充的四字节编码,其范围为 0x81308130 0xFE39FE39 。四字节字符的第一个字节的编码为 0x81 0xFE ;第二个字节的编码范围为 0x30 0x39 ;第三个字节编码范围为 0x81 0xFE ;第四个字节编码范围为 0x30 0x39
 
Unicode
 
1. Unicode 中的 scripts
Unicode 中的 script 指的是一种或多种书写系统中,用来代表文字信息的一个字符或其他书写符号的集合。例如,俄语和乌克兰语分别是西里尔 script 的不同子集。有些 script 支持且仅支持一种书写系统和语言,如亚美尼亚 script ;另一些 scripts 支持多种不同的书写系统,如 Latin script 支持英语、法语、德语、意大利语、越南语和拉丁语。有些语言使用多种不同的书写系统,因此也使用若干个 scripts 。在土耳其语中,阿拉伯语的 script 20 世纪之前使用,但到 20 世纪早期则转变为 Latin script 。汉字书写系统使用在以下语言中:普通话、吴语、粤语、闽语(译者注:台语)、湘语、客家语、赣语、晋语、徽州语、广西平语、侗语、白语(已废弃)、苗语(已废弃)、壮语(已废弃)、日语、韩语(已废弃,只使用于学术文本和报纸中),越南语(用于历史文献、学术文献或出于艺术与审美的考虑)及其他已经失传的语言(契丹文、女真文、西夏文)。
scripts 相补充的是 Unicode symbols Scripts symbols 覆盖了所有的 Unicode 字符,统一发音符号和统一标点符号字符经常具有内在的 script 属性,但是单独的 script 常常也具有自己的发音符号和标点符号。所以很多 script 不仅包括字母,也包括发音符号和其他标记、标点符号、数字甚至其自己的特异性的符号和空白字符。
下图分别为以 Script 为单位和以区块为单位划分 Unicode 字符。
  
关于 CJK 统一表意文字( Han ideographic characters ): Unicode 标准中的“统一表意文字”的说法是西文中一个传统词语,尽管专业语言学家更喜欢“ Sinogram ”这个词。字面上说, ideograph 只适用于某些古代的、原始的汉字形式,这些字的确是来源于表意描述。但绝大部分汉字是后来经组合、假借和其他非表意性的原则发展而来的,但“ Han ideographs ”这个说法仍在英文中沿用。
 
2. Unicode 平面( Plane
Unicode 将代码点( Code Point )分为 17 个平面,其中第 0 个平面(基础多语言平面, Base Multilingual Plane )包含代码点 0x0000-0xFFFF ,第 1 个平面包含 0x10000-0x1FFFF ,以此类推。其实第 0 平面已经包含了绝大部分各种语言的常用字符,位置空间分布示意图如下(左上角为原点,格子中的两位十六进制数表示高位字节):
 
包含汉字( Han ideographs )的区块有:
  • CJK统一表意文字(4E00-9FFF):常用汉字
  • CJK统一表意文字扩展A3400-4DBF):罕用汉字
  • CJK统一表意文字扩展B20000-2A6DF):罕用汉字
  • CJK统一表意文字扩展C2A700-2B73F):罕用汉字
  • CJK兼容表意文字(F900-FAFF):重复字符,可统一的异形字
  • CJK兼容表意文字补充(2F800-2FA1F):可统一的异形字
 
UTF-8
 
1. 简介
全称 UCS Transformation Format �C 8-bit ,是一种对 Unicode 的多字节编码。与 UTF-16 UTF-32 类似, UTF-8 可以表示 Unicode 字符集中的每个字符。与它们不同的是, UTF-8 ASCII 是向后兼容的,并且避免了尾数( endianness )的复杂性。鉴于各种原因, UTF-8 已成为 www 最重要的字符编码,涉及超过半数网页。 UTF-8 使用 1 4 个字节对 Unicode 字符集中的 1,112,064 个代码点中的每一个进行编码。具体而言,使用 1-3 个不等的字节数编码 Unicode 的第 0 个平面。数值较低的代码点使用较少的字节数,使得编码体系较为高效。注意, Unicode 对所有字符进行编码,完成从字符到代码点(如 0x4E00 )的映射,而与字符的具体表示无关; UTF-8 完成由编码到内在表示(字节码)的映射,而不关心某个编码具体代表哪个字符。
 
2. 编码范围
Unicode 字符集的前 128 个字符与 ASCII 码保持 一对一关系,使用一个字节进行编码,使得有效的 ASCII 文本在 UTF-8 编码的 Unicode 下仍然有效。理论上, UTF-8 可以至多编码 2 31 次方字符(即 Universal 字符集起草时的理论上限)。
 
3. 编码规则
如果一个字符用一个字节编码,则最高位是 0 ,其他位给出编码值( 0 127 );
如果一个字符用 k k>=2 字节编码,则第一个字节的前 k 位为 1 ,接着是一个 0 。随后的( k-1 字节全部由“ 10 ”开头。所有字节的剩余位连接起来,形成了 Unicode 代码点值,从 0x80 0x10FFFF 。由此可见:
1 )一个以 0 开头的字节表示单字节字符
2 )一个以 11 开头的字节表示一个多字节字符的开头
3 )一个以 10 开头的字节表示一个多字节字符的非开头
  这样设计使得任何一个字节序列都可以被识别,并不需要从字符串的头部开始。另外由图可见, UTF-8 其实是使用 1-6 个字节来代表一个字符的,即可以表示到 0x7FFFFFFF ,但是据说为了与 UTF-16 兼容,最高的若干位没有用,只用到 0x10FFFF
以下面这个文档为例,文档以 UTF-8 编码。
 
使用 16 进制方式显示,如图:
 
分析如下:
1 )在 UTF-8 中,单个字母是用一个字节表示的,如 A 表示为 0x41 (十进制的 65 ),以此可以定位到汉字“一”被表示为三个字节: 0xe4, 0xb8, 0x80
2 )汉字“一”是 Unicode CJK 统一表意文字区的第一个字符, Unicode 码为 0x4e00 ,既然表示为三个字节,则使用“ 1110xxxx 10xxxxxx 10xxxxxx ”的模板,把 4e00 这十六位编码套进去,正好就是“ e4 b8 80 ”;
3 fileformat unix ,因此换行符是一个 <NL> ,即 0x0a
4 )上述文档在 Ubuntu 里说大小为 29 bytes ,数一数的确如此。
 
六 文泉驿
 
1. 简介
作为几千年中华文明的见证,浩瀚传统文化传承的载体,汉字是让我们每一个中国人引以为豪的东方文明标志之一。我们的祖先创造汉字,书写汉字,利用汉字和汉语的无穷魅力创造出让人叹为观止的文学、艺术。而今天进入了计算机时代的我们,虽然不再古人一样手持毛笔,批著简帛,但我们的生活仍然无时无刻离不开汉字。
可以毫不夸张的讲,汉字是世界上已知的最为庞大的符号系统。早在殷商时期,我们的先人就创造出了数目巨大的甲骨文,从上万片发掘的甲骨中整理出来的单字就有四千余个。东汉许慎编撰的“说文解字”,收录汉字 9,353 个。至清朝康熙年间,由段玉裁等人收集整理的“康熙字典”收录汉字竟达 47,035 之多。加上少数民族文字,各种古代典籍上曾经出现但并未广泛使用的古汉字和异体字,汉字总数多达十万以上。作为现代计算机系统通用编码的统一码 (Unicode) 在最新发布的 5.2 版中共收录汉字 ( 包括简体、繁体,以及日、韩、越等地区使用的汉字 ) 74,394 。(注:微软的中易宋体的最新版本只有 42,809 个字)
我们是一群致力于在计算机世界中推广汉字,丰富电子汉字资源的志愿者。我们希望通过自己无私的劳动,使得无论您在世界上任何一个角落,都可以免费地获得我们的电子汉字资源,能够流畅地通过汉字进行交流。“文泉驿”是以上述目标为宗旨而自发创建的非盈利性组织。
 
2. 文泉驿正黑( WenQuanYi Zen Hei
文泉驿正黑体是一个 " 自由字体 " 。该字体包含了所有常用简体中文、繁体中文所需要的汉字 ( 最新版本包含超过 27842 个汉字,完整覆盖 GB2312/Big5/GBK 以及 GB18030 标准字符集 ) 。该字体同时还包含了日文、韩文和其他几十种语言符号。除此以外,该字体还嵌入了最新版本的文泉驿点阵宋体的中英文点阵,使得屏幕汉字显示清晰锐利,易于阅读。
作为黑体中文字体,文泉驿正黑为非衬线字体,笔画对比度明显,特别适合屏幕汉字显示以及文档标题字体。
 
3. 文泉驿微米黑( WenQuanYi Micro Hei
文泉驿微米黑是一个 " 自由字体 " 。该字体包含了所有常用简体中文、繁体中文所需要的汉字 ( 最新版本包含超过 20932 个汉字,完整覆盖 GB2312/Big5 以及 GBK 标准字符集 ) 。该字体同时还包含了日文、韩文和其他几十种语言符号。以外,该字体还包含了高质量的 Droid Sans 拉丁符号和 Droid Sans Mono 等宽字体,并内置 Hinting Kerning 信息。微米黑字体文件极小,特别使用于便携式电脑设备。
 
4. 文泉驿点阵宋体( WenQuanYi Bitmap Song
文泉驿点阵宋体是一个 " 自由中文字体 " 。该字体包含了所有常用简体中文、繁体中文,日文及韩文所需要的汉字 ( 最新版本包含超过 27842 个汉字,完整覆盖 GB2312/Big5/GBK/GB18030 标准字符集 ) 。该字体同时还包含了英文、日文、韩文和其他多种语言符号。该点阵字体包含五个屏幕常用字号 (9pt-12pt) ,逾 21 万汉字点阵,这些点阵都经过参与者和组织者的精心设计和调整,手工优化后的汉字点阵显示清晰锐利,特别易于屏幕阅读使用。
我们目前提供下载的文泉驿点阵宋体只能够在 Linux/Unix 系统上使用。在 Windows 上使用该字体,请下载文泉驿正黑体,正黑体嵌入了所有 GBK 汉字点阵,在 9-12pt 范围内,将自动使用点阵宋体显示。
 
七 正则表达式
 
1. Unicode 字符的一般正则表达式表示
支持 Unicode 的程序中的正则表达式通常支持 \uNUM 原序列,用来匹配一个具体的 Unicode 字符。这个数值通常是一个 4 位十六进制数,例如, \uC0B5 的意思是“匹配编号为 U+C0B5 Unicode 字符”,而没说具体需要比较哪些字节,因为具体的字节是由代表这个 Unicode 代码点的编码方式在内部决定的。如果程序内部使用的是 UTF-8 编码,这个字符就用 3 个字符表示。不过使用支持 Unicode 程序的用户,并不需要关心这个。
为了匹配任何一个 Unicode 字符,应该用 \X ,这相当于 Unicode 中的点号。在 Java 中,用 \uFFFF FFFF 是代码点)来匹配某个特定的 Unicode 字符。
 
2. Perl PCRE Unicode 字符的正则表达式表示
Perl PCRE 中,并不支持 \uFFFF 这样的语法,而是使用 \x{FFFF} 。例如, \x{1234} 不会和“匹配 \x 1234 次”混淆,而是永远代表 U+1234 这个 Unicode 字符; \x{1234}{5678} 则代表匹配 U+1234 这个 Unicode 字符整整 5678 次。
Perl PCRE 还是极少数的支持基于 Scripts Unicode 进行匹配的正则表达式引擎!方法是 \p{Script_Name} 例如, \p{Bopomofo} 匹配一个注音符号字母, \p{Han} 匹配一个汉字。此外还支持基于区块的匹配,如 \p{InCJK_Unified_Ideographs} 匹配所有 CJK 统一表意文字区的字符(等同于 U+4E00…U+9FFF
Perl 中读取以 UTF-8 编码的文件,还有另一个问题:当使用 <> <FILEHANDLE> 等方式读取文件时, perl 会把文件视为一系列字节流,而 UTF-8 是变长字节编码的,想以字符(而不是字节)为单位来处理,则必须进行解码。
例如,运行如下代码
 
打印出来的是每行一个带问号的小菱形,说明字符串 $_ 中每个单元是一个字节。要解决这个问题,有两种思路:一方面使用 binmode 改造句柄,使之以 UTF-8 方式读取,如下:
 
但是这样有个问题是第一个字符不能正常读取!之后的都正常!这是为什么啊!另一个思路是对读入的字符串进行处理,即告诉 perl 这个字符串(本质上是字节序列)要以 UTF-8 的多字节方式解析。这一过程是 decode ,因此用以下方法可以解决问题:
 
读入之后,就可以用 \x{abcd}, \p{Han} \p{InCJK_Unified_Ideographs} 等方式对其进行正则表达式处理了。
 
3. Vim Unicode 正则表达式的支持
         作为最强大的文本编辑器, Vim 对正则表达式的支持是人尽皆知的。而且,毕竟是文本编辑器,执行个查找啊替换啊这种处理会比用 perl 直观得多。但是,对于 Unicode 字符的支持, Vim 采用的正则表达式引擎却远比不上 Perl(图为节选)
 
有人说,为什么 Vim 不用 PCRE 呢?回复说, Vi Perl 出来的早得多,应该问为什么 Perl 不跟 Vi 学。无论如何,在 Vim 里匹配 Unicode 字符会遇到一点麻烦:你可以用 /\u4e00 匹配“一”,也可以用 /[\u4e00-\u4eff] 匹配 Unicode 表中的第一行汉字(一、丁、万、三、上……),却不能用 /[\u4e00-\u9fff] 匹配 CJK 统一表意文字区块中的所有文字!不知道是不是我的使用有问题!
 
Ubuntu中的字符映射表(Character Map
        
这是 Ubuntu 中相当于 Windows “字符映射表”的软件,可以在 Applications -> Accessories 中找到。且不说以文泉驿微米黑显示的字符表有多好看,就说这个 Character Details 就做得非常帅,给出的信息包括: UTF-8 编码方式、 XML 实体表示形式、英文释义、普通话发音、广东话发音、日语发音、韩语发音!
工作过程中有时候需要看看 Unicode Scripts ,或者查找某个字符的 Unicode 码,或者要 copy 某种北欧语言的奇怪字符,都可以用 Character Map
        
另外,字符映射表支持根据字符查找与根据 Unicode 值查找:
 
在这两天的折腾过程中,帮了不少忙。
 
本来只是想解决 Perl 处理 UTF-8 中文文档的问题,不小心扯出来这么多东西。以上是这两天折腾的全部结果,折腾了 24 小时……没有苦劳也有疲劳啊。
 
九 参考资料
 
  • http://en.wikipedia.org/wiki/Windows_code_page
  • http://en.wikipedia.org/wiki/UTF-8
  • http://en.wikipedia.org/wiki/Plane_(Unicode)
  • http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters
  • http://en.wikipedia.org/wiki/List_of_languages_by_writing_system
  • http://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines
  • http://en.wikipedia.org/wiki/Code_pages
  • http://en.wikipedia.org/wiki/CJK_Unified_Ideographs
  • http://en.wikipedia.org/wiki/Basic_Multilingual_Plane
  • http://zh.wikipedia.org/wiki/Gb2312
  • http://zh.wikipedia.org/wiki/GBK
  • http://zh.wikipedia.org/wiki/GB18030
  • http://www.utf8.com/
  • http://www.unicode.org/versions/Unicode5.2.0
  • http://www.unicode.org/reports/tr18/
  • http://www.unicode.org/charts/
  • http://www.regular-expressions.info/charclass.html
  • http://wenq.org/index.cgi?ZenHei
  • http://wenq.org/index.cgi?MicroHei
  • http://wenq.org/?BitmapSong
  • http://vim.wikia.com/wiki/Perl_compatible_regular_expressions
  • http://perldoc.perl.org/perlunicode.html
  • http://msdn.microsoft.com/en-us/library/20bw873z.aspx
  • http://forum.ubuntu.org.cn/viewtopic.php?t=244756

你可能感兴趣的:(编码,职场,汉字,休闲)