欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    UCS2 UCS4 中文字符编码 TTF字库之间的关系.docx

    • 资源ID:6508682       资源大小:260.86KB        全文页数:15页
    • 资源格式: DOCX        下载积分:12金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要12金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    UCS2 UCS4 中文字符编码 TTF字库之间的关系.docx

    1、UCS2 UCS4 中文字符编码 TTF字库之间的关系字体和字符编码的关系Sunny.Man一、事件的起因“回车键“”这个标记怎么样才能显示在文本框内?”一个哥们在群里问。我把这个符号复制到WORD里,然后按“ALT+X”看到了它的UNICODE码,然后告诉那哥们这个符号的Unicode码是0x21B5。顺手我把它复制到了我正打开的UE文件里时,它居然变成了一个”?”,马上查看它的十六进制码也变成了0x3F。为什么会有这个变化?我又把它复制到了WINDOWS的记事本里,记事本里却显示的好好的”。我想更清楚的看一下是不是这个符号,我点击字体,然后选择了“新宋体”,并设置了初号。结果更是另我大跌眼

    2、镜,居然变成了一个“ ”。为什么呢。心中似乎有答案,但又不能完全说明白。还好我有度娘,按着我心里的思路咱一路XX,最终我得到了我认为合理的解释,由于具体的是不是这么回事,我没验证过。所以大家仅供参考。再弄懂这些乱七八遭的事前,先复习了一下相关概念。二、字符的编码1.什么是字符集字符(Character)是文字与符号的总称,包括文字、图形符号、数学符号等。“*“是一个字符“”也是一个字符。一组抽象字符的集合就是字符集(Charset)。字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集。一组有共同特征的字符也可以组成字符集,比如繁体

    3、汉字字符集、日文汉字字符集。字符集的子集也是字符集。2.字符编码计算机只能处理0和1,如果计算机要处理各种字符就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding)。 制定编码首先要确定字符集,并将字符集内的字符排序,然后和二进制数字对应起来。根据字符集内字符的多少,会确定用几个字节来编码。 每种编码都限定了一个明确的字符集合,叫做被编码过的字符集(Coded Character Set),这是字符集的另外一个含义。通常所说的字符集大多是这个含义。说得通俗些就是0和1只能表示两个字符,为了表示人类使用的字符,就把它们编成一个个的二进制串,每个串表示一个字符。如果你是制度

    4、的创立者你完全可以规定,0000001就是”a”,而不用使用(97)这个串.可惜你不是计算的的编码发明者,所以得随大家一起用人家编好的。当然了这其中的编码都是科学合理的,也不是随心所欲的。3.常见字符集 3.1ASCII: American Standard Code for Information Interchange,美国信息交换标准码。 目前计算机中用得最广泛的字符集及其编码,由美国国家标准局(ANSI)制定。 它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。 ASCII字符集由控制字符和图形字符组成。 在计算机的存储单元中,一个ASCII码值占一个字节(8个二进制

    5、位),其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。 奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1。 偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。 下表就是ASCII编码表:ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符 0 NUT 32 (space) 64 96 、1 SOH 33 !65 A 97 a 2 STX 34 ”66 B 98 b 3 ETX 35 # 67 C 99 c 4 EOT 36 $

    6、68 D 100 d 5 ENQ 37 % 69 E 101 e 6 ACK 38 & 70 F 102 f 7 BEL 39 , 71 G 103 g 8 BS 40 ( 72 H 104 h 9 HT 41 ) 73 I 105 i 10 LF 42 * 74 J 106 j 11 VT 43 + 75 K 107 k 12 FF 44 , 76 L 108 l 13 CR 45 - 77 M 109 m 14 SO 46 . 78 N 110 n 15 SI 47 / 79 O 111 o 16 DLE 48 0 80 P 112 p 17 DCI 49 1 81 Q 113 q 18

    7、DC2 50 2 82 R 114 r 19 DC3 51 3 83 X 115 s 20 DC4 52 4 84 T 116 t 21 NAK 53 5 85 U 117 u 22 SYN 54 6 86 V 118 v 23 TB 55 7 87 W 119 w 24 CAN 56 8 88 X 120 x 25 EM 57 9 89 Y 121 y 26 SUB 58 : 90 Z 122 z 27 ESC 59 ; 91 123 28 FS 60 94 126 31 US 63 ? 95 127 DEL ASCII收录了空格及94个“可印刷字符”,足以给英语使用。 但是,其他使用拉丁字

    8、母的语言(主要是欧洲国家的语言),都有一定数量的变音字母,故可以使用ASCII及控制字符以外的区域来储存及表示。 除了使用拉丁字母的语言外,使用西里尔字母的东欧语言、希腊语、泰语、现代阿拉伯语、希伯来语等,都可以使用这个形式来储存及表示。 很明显这种编码表示的字符范围很窄,无法表示中文字符。3.2汉字编码3.2.1区位码国标码1980年,为了使每一个汉字有一个全国统一的代码,我国颁布了第一个汉字编码的国家标准: GB2312-80信息交换用汉字编码字符集基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。这个标准用两个数来编码汉字和中文符号。第一个数称为“区

    9、”,第二个数称为“位”。所以也称为区位码。1-9区是中文符号,16-55区是一级汉字,56-87区是二级汉字。 国标码是一个四位十六进制数,区位码是一个四位的十进制数,每个国标码或区位码都对应着一个唯一的汉字或符号,但因为十六进制数我们很少用到,所以大家常用的是区位码,它的前两位叫做区码,后两位叫做位码。用一句简单的话说就是区位码人使用起来比较方便,而国标码是为了给计算机使用。当然一会讲到两者的关系。总之这个GB2312-80就是一张大表,这张94*94的大表规定了哪个汉字用哪个编码(数字)来代替。例如”土”的区位码4533。它表示“土“字在45区的33位.其在表中的位置可以如下图所示:那它又

    10、是如何转为国标码的呢。按规定把区位码的区和位分别+160就是相应的国标码, 45+160=205=0xCD,33+160=193=0xC1那么0xCDC1就是”土“的国标码。为什么要加上0xA0呢,主要是为了和ASCII的编码区分开来,以便让计算机知道是一个字节的英文还是两个字节的中文,现在计算机知道了所有的中文第一个字节都大于0xA0,由于经常说起人们还给他起了一个名字(Leading Byte)。这种表示的字符集又叫MBCS因为WINDOWS只使用了两个字节所以又叫DBCS。3.2.2大端和小端模式现在我们知道了在计算机里是用两个字节来表示一个中文字符的。现在有一个问题。当我们打开一个文本

    11、文件,并读取到了“D7 D6 B7 FB BA CD B1 E0 C2 EB”这十个字节。现在我们知道D7 D6根据国标码规则应该是一个汉字,但这究竟应该是0xD7D6呢,还是0xD6D7呢。这就是有名的大端模式和小端模式。big endian和little endian(大端模式和小端模式) “endian”这个词出自格列佛游记。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,一个皇帝送了命,另一个丢了王位。我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾

    12、”和“小尾”。所谓大端模式就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。小端模式就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。下面是把一个LONG型的数据0x12345678存放到内存里里两种方式的排列方法:在我的X86结构的计算机里,用的是小端模式。那么其中”D7D6”就是国标码的”字”这个字符。3.2.3代码页现在我们知道了在中国大陆我们使用我们的GBK,那在台湾,在日本,在韩国使用什么呢?没错如你所猜测的,每个地区都有每个地区的标准。我们的叫GBK而台湾的就叫Big5。由于自己制定的标准那么就出现了一个编码按不同的编码出现两个符号的情况。0xD1C6这

    13、个国标码在GB2312的编码下是一个”哑”字,而在Big5的编码下却是一个“字。那么WINDOWS到底应该把这个编码译为哪个字符呢。又是如何译的呢?这就不得不说代码页。代码页(Code Page)是个古老的专业术语,据说是IBM公司首先使用的。代码页和字符集的含义基本相同,代码页规定了适用于特定地区的字符集合,和这些字符的编码。可以将代码页理解为字符和字节数据的映射表。Windows为自己支持的代码页都编了一个号码。例如代码页936就是简体中文 GBK,代码页950就是繁体中文 Big5。代码页的概念比较简单,就是一个字符编码方案。这个方案由当地的编码机构进行制定。但要说清楚Windows的A

    14、NSI代码页,就要从Windows的区域(Locale)说起了。微软为了适应世界上不同地区用户的文化背景和生活习惯,在Windows中设计了区域(Locale)设置的功能。Local是指特定于某个国家或地区的一组设定,包括代码页,数字、货币、时间和日期的格式等。在Windows内部,其实有两个Locale设置:系统Locale和用户Locale。系统Locale决定代码页,用户Locale决定数字、货币、时间和日期的格式。我们可以在控制面板的“区域和语言选项”中设置系统Locale和用户Locale:每个Locale都有一个对应的代码页。系统Locale对应的代码页被作为Windows的默认代

    15、码页。在没有文本编码信息时,Windows按照默认代码页的编码方案解释文本数据。这个默认代码页通常被称作ANSI代码页(ACP)。ANSI代码页还有一层意思,就是微软自己定义的代码页。在历史上,IBM的个人计算机和微软公司的操作系统曾经是PC的标准配置。微软公司将IBM公司定义的代码页称作OEM代码页,在IBM公司的代码页基础上作了些增补后,作为自己的代码页,并冠以ANSI的字样。我们在“区域和语言选项”高级页面的代码页转换表中看到的包含ANSI字样的代码页都是微软自己定义的代码页。例如:874 (ANSI/OEM - 泰文) 932 (ANSI/OEM - 日文 Shift-JIS) 936

    16、 (ANSI/OEM - 简体中文 GBK) 949 (ANSI/OEM - 韩文) 950 (ANSI/OEM - 繁体中文 Big5) 1250 (ANSI - 中欧) 1251 (ANSI - 西里尔文) 1252 (ANSI - 拉丁文 I) 1253 (ANSI - 希腊文) 1254 (ANSI - 土耳其文) 1255 (ANSI - 希伯来文) 1256 (ANSI - 阿拉伯文) 1257 (ANSI - 波罗的海文) 1258 (ANSI/OEM - 越南)我们不能直接设置ANSI代码页,只能通过选择系统Locale,间接改变当前的ANSI代码页。微软定义的Locale只使

    17、用自己定义的代码页。所以,我们虽然可以通过“区域和语言选项”中的代码页转换表安装很多代码页,但只能将微软的代码页作为系统默认代码页。在Windows 2000以后,Windows统一采用UTF-16作为内部字符编码。现在,安装一个代码页就是安装一张代码页转换表。通过代码页转换表,Windows既可以将代码页的编码转换到UTF-16,也可以将UTF-16转换到代码页的编码。代码页转换表的具体实现可以是一个以nls为后缀的数据文件,也可以是一个提供转换函数的动态链接库。有的代码页是不需要安装的。例如:Windows将UTF-7和UTF-8分别作为代码页65000和代码页65001。UTF-7、UT

    18、F-8和UTF-16都是基于Unicode的编码方案。它们之间可以通过简单的算法直接转换,不需要安装代码页转换表。在安装过一个代码页后,Windows就知道怎样将该代码页的文本转换到Unicode文本,也知道怎样将Unicode文本转换成该代码页的文本。3.2.4如何把文本文件打开的当我们打开了文本文件Test.txt,并知道它有十个字节的数据 “D7 D6 B7 FB BA CD B1 E0 C2 EB”。Windows首先根据locale来查看当前的代码页是多少,当然我的计算机是936于是它按GB2312来查找相应的字符。它得到DBCS字符串”字节和字符”。没错,代码页就是这么有用而且巧妙

    19、,微软不管你什么规则,不管你什么字符,总之我按你给我的标准来。至于你是什么微软不关心。由于各代码页支持的字符范围不同,我们一般不会直接在代码页间转换文本。需要我们转换文本时,我们先把A(要转换的文本)转换为unicode码,然后再把这个unicode码转换为B(转换后的文本)。3.2.5如何把简体中文转换为Big5编码的繁体中文将GBK中文简体编码的文本转换到Big5繁体编码的正确步骤应该是:1.将GBK中文简体编码映射到GBK的中文繁体的; 2. GBK的中文繁体转换为Unicode中文繁体文本; 3. Unicode中文繁体的文本转换为Big5繁体的文本。1. 将GBK中文简体编码映射到G

    20、BK的中文繁体的LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);int nLength = LCMapStringA(lcid,LCMAP_TRADITIONAL_CHINESE,szGBKString,-1,NULL,0);/szGBKString =char * srcSimplifiedChinesechar* pBuffer=new charnLength+1;LCMapStringA(lcid,LCMAP_TRADITIONAL_CHINESE,szG

    21、BString,-1,pBuffer,nLength);pBuffernLength=0;2. GBK的中文繁体转换为Unicode中文繁体文本;UINT nCodePage = 936; /GB2312 int nLength=MultiByteToWideChar(nCodePage,0,szGBString,-1,NULL,0);/ szGBString GBK的中文字符串 wchar_t* pBuffer = new wchar_tnLength+1; MultiByteToWideChar(nCodePage,0,szGBString,-1,pBuffer,nLength); pBu

    22、ffernLength=0;/pBuffer为UNICODE码3. Unicode中文繁体的文本转换为Big5繁体的文本。UINT nCodePage = 950; /BIG5int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);char* pBuffer=new charnLength+1;WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);pBuffernLength=0;为什么要

    23、这样转换呢?如果你有一张区位码表你就会发现,一个简体的“门”( 3537)和一个繁体的“門”( 7376)在区位码里是两个编码。而BIG5里没有”门”相对应的字的,所以如果直接把GBK的”门”转换为Unicode的“门“,然后unicode的”门”到转换为Big5“門”的时候,就找不到这个字就会出现”?”,请记住这个?本文开头就出现了一个”?”。为了避免这种情况,我们把GBK的所有简体字,用LCMapStringA映射为繁体字。但GBK的繁体字的编码也不是Big5的编码,两者没有任何联系,但两者在unicode里是同一个编码。没错UNICODE所有的编码都是唯一的。3.3Unicode3.3.

    24、1UCS-2 UCS-4Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是UniversalMultiple-Octet Coded Character Set,简称为UCS。UCS可以看作是Unicode Character Set的缩写。历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO10646项目,Unicode协会开发了Unicode项目。在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作

    25、成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是ISO 10646-3:2003。UCS只是规定如何编码,并没有规定如何传输、保存这个编码。例如“汉”字的UCS编码是6C49,我可以用4个ascii数字来传输、保存这个编码;也可以用utf-8编码:3个连续的字节E6 B1 89来表示它。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UT

    26、F-8的一个特别的好处是它与ISO-8859-1完全兼容。UTF是“UCS Transformation Format”的缩写。IETF的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是InternetEngineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。目前Windows的内核已经支持Unicode字符集,这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK,Windows不可能不支持现有的

    27、编码,而全部改用Unicode。Windows使用代码页(code page)来适应各个国家和地区。code page可以被理解为前面提到的内码。GBK对应的code page是CP936。微软也为GB18030定义了code page:CP54936。但是由于GB18030有一部分4字节编码,而Windows的代码页只支持单字节和双字节编码,所以这个code page是无法真正使用的。UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏: UCS-2有216=655

    28、36个码位,UCS-4有231=2147483648个码位。UCS-4根据最高位为0的最高字节分成27=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目

    29、前的UCS-4规范中还没有任何字符被分配在BMP之外。UCS-4分配示意图3.3.2UTF-8和UTF16UTF-8就是以8位为单元对UCS进行编码。从UCS-4到UTF-8的编码方式如下:Ucs-2到UTF8编码如下UCS-2编码(16进制) UTF-8 字节流(二进制) 0000 - 007F 0xxxxxxx 0080 - 07FF 110xxxxx 10xxxxxx 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx 例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10

    30、xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11101 10001001,即E6 B1 89。 UTF-16以16位为单元对UCS进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。3.3.3BOM但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?Unicode规范中推荐的标记字节顺序


    注意事项

    本文(UCS2 UCS4 中文字符编码 TTF字库之间的关系.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开