编程与编码

本文详细介绍了字符编码的历史,从ASCII到Unicode的发展,以及Unicode如何解决多语言字符编码问题。文章探讨了Unicode的不同编码形式如UTF-8、UTF-16,以及与中文、日文字符集如GBK、Big5的转换关系。还讨论了编码转换的实现和编码检测的技术,并提供了相关资源链接。
摘要由CSDN通过智能技术生成

编程与编码

问题由来

在计算产生的那天开始,应该说计算产生之前,编码问题就会一直伴随着信息编码的问题。这是由于计算机硬件逻辑上决定的,电路的二进制表达只能是数字上的意义,每一比特就只能表达 0 或 1,每个字节也只能表达 0-255。当需要通过计算机表达文字信息时,问题就跟着来了。

计算机只能存储数值,为此文字信息也需要通过数值的形式来存储。最原始的文字是点阵文字,定义屏幕上一个矩形,标记不同的点位的颜色信息,从而赋予字形图像 Glyph 相应的文字信息。例如字母A、汉字“中”可以这样用一个5x5的点阵定义,☆、★号分别代数值 0、1,★表示在显示器上用深颜色来表示文字的笔划:

☆☆★☆☆   ☆☆★☆☆
☆★☆★☆   ★★★★★
★☆☆☆★   ★☆★☆★
★★★★★   ★★★★★
★☆☆☆★   ☆☆★☆☆

显示设备的分辨率是一项重要的参数,单位是像素点每英寸 DPI(Dot per Inch),1 英寸约为25.4 millimetres 毫米。在选购显示器所说的分辨率如1366*768,指的是显示器总的显示像素数量,并不是DPI数值。以前常见的分辨率是72DPI,现在还有更高的 96DPI、120DPI,分辨率越高在相同的显示面积上显示的点数越多,意味着显示的内容越精细。在96DPI的Win7系统上,每平方英寸可以显示9磅大小的雅黑中文字符为8个,1磅约等于0.353毫米,如果在72DPI设备上,1磅刚好就是一个像素宽。2.83磅等于1毫米,28号字大概就是一厘米高的字,约相当于中文字号中的一号字。如果汉字是正方形,那么每个字就是12x12个像素点。所以只要有足够的像素点,就算再复杂的字符也可以用这种点阵来定义,当然现在更先进的技术已经不用点阵图形,而是用可以任意缩放的矢量图形来定义字体了,比如说TrueType字体,开源的 FreeType。而这此文件符号定义好后,由于符号占用内存较大不便直接使用。因而需要通过一个数值对应一个文字符号的方式来使用,当需要显示一个字符时只需要给出字符的对就数值就可找到字体符号的定义,并输出到屏幕上,而这个值就称为码点 Code Point。

英语国家是计算机的发明国,而英文只由26个字母构成,所以就形成了第一个字符集美国标准信息交换代码 ASCII(American Standard Code for Information Interchange),所有字符只需一个字节表达。在ASCII中定义了全部大小写字母和常用标点符号及一些不可显示的功能字符,A的定义的值为0x41,a的值定义为0x61,0的值定义为0x30。因此,在程序中想要显示字母A时,只需要将0x41对应的字符显示在屏幕上就可以了。

当计算机在全世界流行起来,不同地方的语言文字的差异带来了不同字符集的需要。就中文来说,在DOS时代,WPS还是用点阵来显示汉字的,当年还用专门的硬件来做字库。而常用汉字就有几千个,如果算上那些不常露脸的字就上万的数量。直到1980年中文字符集《信息交换用汉字编码字符集》才由中国国家标准总局发布,1981年5月1日开始实施的一套国家标准是GB 2312—1980,收录汉字6763个,非汉字图形字符682个。这样一个庞大的字符集就需要多个字节来表达,这就形成了多字节字符集的概念,中日韩字符集是典型的多字符集。SBCS、DBCS、MBCS,分别表示单字节字符集 single-byte character set,双字节字符集 double-byte character set 和多字节字符集 multi-byte character set。

当计算机信息交换越来越频繁,就需要更便利的文字编码方案,Unicode 作为一个全球通用的字符集就这样出来了,它收录了全球各种文字符号,因此它具有很强的通用性。Addison Wesley 出版的《The Unicode Standard Version 5.0》无疑是全球化语言的一本小百科,值得一看!官方提供最新版 Unicode 6.3 码表查询 Character Code Charts 或 Understanding Unicode™ - I。还有一个查询工具 Unibook Character Browser 用来查询已收录字符集、编码方案及代码页等数据。

在 Unicode 出现前,Windows系统作为一个多语言的操作系统,它是通过一个特定字符集来实现多语言的。例如 Windows 95 的简体中文版和繁体中文版分别使用 GBK、Big5字符集编码,这些不同的字符集在 Windows 平台上就称为代码页 Code Pages,这是微软特有的称谓。例如:

cp932 - 日文
cp936 - 简体中文 GBK
cp949 - 韩文
cp950 - 繁体中文 BIG5
65000 — UTF-7 Unicode
65001 — UTF-8 Unicode

编码问题是程序开发中的基础技术,不掌握它确实会困扰不少人,像网页上经常看到的乱码。还有我以前使用Windows 98 英文版时遇到的问题,整个硬盘的中文名文件都被拒绝访问了。还要使用像什么南极星通、MagicWin之类的软件来进行转码处理。所谓乱码问题,就是编码和解码方案不统一产生的问题,比如说用 UTF-8 编码来解释 GB2312 编码的文件,那是肯定会乱码的。内码也是一个常让人搞不清楚的用词,用人就问GBK和GBK内码有什么区别?其实这个问题问法就不对,内码就是一个系统内部使用的编码方案。如中文版 Windows 98 使用的是 GBK 编码,而繁体版使用的是 Big5。因此数据交换时,就要考虑系统的内码是否兼容,如果拿繁体版Windows 95来处理简体版系统发过来含有中文字符的电子邮件,就会看到一堆的乱码了。

比如说同一个“汉”字,在GB18030的编码为 0xBABA,UTF-16编码为 0x6C49,汉字作为一个大数量的字符集,在各种编码间的映射关系也是十分混乱的,转换工作基本上靠查表,字符编码值可以使用 Editplus、Hex Workshop等软件来查看:

BA BA       GB18030 
E6 B1 89    UTF-8
49 6C       UTF-16 little endian(FF FE) 
6C 49       UTF-16 little endian(FE FF)

即使是同样的单字节编码,比如说码点 0xA4 在 ISO-8859-1 和 ISO-8859-15 字符集中分别表示 ¤ 和 €。同样的码值 ,显示结果不同,是因为使用的字体不同,或者字体相同,但是映射的区域不同。现在的Unicode字体可以包含大量的字符定义,在打开文件时,软件需要知道用什么字符集去解释码值,这就是字符集 存在意义。

细说Unicode

历史上, 有两个独立的, 创立单一字符集的尝试。一个是国际标准化组织(ISO) 的 ISO 10646 项目,于1993年发布,简称 UCS,全称 Universal Multiple-Octet Coded Character Set。 另一个是由(一开始大多是美国的)多语言软件制造商组成的协会组织的 Unicode 项目。幸运的是, 1991年前后, 两个项目的参与者都认识到, 世界不需要两个不同的单一字符集. 它们合并双方的工作成果, 并为创立一个单一编码表而协同工作。两个项目仍都存在并独立地公布各自的标准, 但 Unicode 协会和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 标准的码表兼容, 并紧密地共同调整任何未来的扩展。参考 Olle Järnefors 这篇文章《Short overview of ISO/IEC 10646 and Unicode》

在 Unicode 系统内,每一个符号都有一个名字,以全大写字母表示,如基本拉丁字母 A 的 Unicode 名字就是 LATIN CAPITAL LETTER A,连字符 - 就叫做 HYPHEN-MINUS,码值 U+002D。Unicode的出现,使得世界上大多数语言符号都实现电子化,当然作为最多文字符号的中国自然是最值得高兴的事,你看来☯这样国粹都可以当作字符来编码,这还得感谢那批在为标准化工作的专业人员。这些多功能字符定义在 U+2600-U+26FF,通过码表可以查看到。

开始 UCS 方案使用2字节编码,如 U+0032 表示空格&

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值