
原帖由 红衣主教 于 2010-12-10 18:58 发表
体会上面编码的设计,可能还包含另外一重好处,这样可以使编码的高字和低字内在区分,文本编码作为一个数据流即使中间偶然出现个别错误,可以将错误限制在局部范围,不至于造成高字和低字可能发生的混淆继续蔓延殃及下文,有一定程度的容错能力,不知这样理解是否恰当。
UTF-16编码格式中代理对的处理
代理对里面的两个代理分别称之为高16位代理编码单元(或引导代理),和低16位代理编码单元(或尾随代理)。由于引导代理和尾随代理的编码空间分别在U+D800到U+DBFF之间和U+DC00到U+DFFF之间,所以首尾两个代理总共可以组合出(DBFF-D800+1)*(DFFF-DC00+1)=1048576个代理对,也就是总共可以表示1048576个增补编码点。另一方面,目前Unicode标准所确定的16个增补平面的编码点容量的总和也是65536*16=1048576个。
在UTF-16编码格式里面:引导代理的后面应该是一个尾随代理,而尾随代理的前面就应该是一个引导代理;不能出现一个引导代理的后面是一个非代理的普通UTF-16编码单元的情况,也不能出现一个引导代理的后面还是一个引导代理的情况,UTF-16文本(字符串)的最后一个编码单元不能是引导代理;不允许出现一个尾随代理的前面是一个尾随代理的情况,也不允许出现一个尾随代理的前面是一个非代理的普通UTF-16编码单元的情况,UTF-16文本(字符串)的第一个编码单元不能是尾随代理;单独的一个代理(不管是引导还是尾随代理)编码单元是不合法的,代理必须以一个“引导代理+尾随代理”编码对的形式出现。UTF-16的这种“代理对”编码规则保证了文本处理程序能正确地访问和处理包括了BMP和增补字符的UTF-16 编码单元序列,并将两者之间发生冲突的可能性减到了最小。
因为引导代理和尾随代理编码单元被规定在一个特定范围内取值,所以很简单的一个原则就是:凡是编码值在代理编码范围内的编码单元就是“代理编码单元”,否则就是“BMP字符编码单元”。由于BMP字符和代理编码单元分别在各自独立的编码范围内进行编码,所以对于一个符合格式规范的UTF16编码单元来讲,它必须满足以下三个条件之一:
· 非代理编码单元必须是一个取值在0到D7FF或E000到FFFF之间的编码点;
· 引导代理必须是代理对中的第一个编码单元;
· 尾随代理必须是代理对中的第二个编码单元。
在UTF-16编码格式里面,一个Unicode 字符由一个或两个编码单元组成。所以如果想在一个UTF-16编码序列里面判断某个编码单元是属于哪个字符的话,你需要检查那个编码单元的值,然后根据编码单元的类型决定是否还需要向前或向后检查一个相邻的编码单元(可以不必理会除了前后相邻的两个编码单元之外的其他编码单元)的值。
在处理UTF-16编码格式文本时,为了确保文本数据的完整性,绝对不能把任意一个代理从代理对中拆出来,也不能在代理对中间插入另一个字符。此外即使文本中某些字符数据遭到破坏,其影响也只是局部性的,这一点和大多数的多字节编码标准如GBK、Big5 等不同。单独的一个UTF-16编码单元出错涉及的只是一个字符。由于UTF-16编码格式的“非迭代”特性,像这种类型的错误是不会传递到文本的其他部分去的。
因为在大多数的文本数据中,代理对(增补字符)出现的概率是很小的,很多情况下我们处理的还是非代理编码单元(BMP 字符)。虽然如果编程时要考虑到文本中可能出现的不同存储长度的字符(BMP 字符是单16位编码,增补字符是双16位编码)并相应做出不同的处理的话,会比单纯只考虑16位编码的处理程序在性能上要逊色一些,不过应该看到的是,现有的遵循定长16位编码规范但不能处理代理对的程序只需做很小的一点修改就可以同时处理BMP 字符和增补字符了。抛开性能这个硬性指标不谈(因为处理程序要考虑的情况越复杂,处理所需的时间就越长,这不是单纯通过技巧可以绕开的客观规律),单从应用需求的角度考虑,软件设计时同时把代理对和非代理编码单元的处理考虑进去还是有必要的。
原帖由 slt 于 2010-12-13 00:32 发表
“举个例子看看” 是 “3E 4E 2A 4E 8B 4F 50 5B 0B 77 0B 77 ”,假設在 2A 和 4E 之間,多了一個 00,就變成 “举*譎偏୷”。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Language Pack\SurrogateFallback
原帖由 红衣主教 于 2010-12-13 21:49 发表
我觉得上面两位讨论的见解并无实质性冲突,只是在各自默认的前提下看这个问题,才有一些表叙差异。
还有另一个稍有关联的问题请教谢兄,关于 Windows 多语言文本的后援字体(Fallback Font)问题,在注册表 分支下 ...
Font fallback is internal to Uniscribe, and applications cannot add new fallback fonts or modify existing ones.
(http://msdn.microsoft.com/en-us/goglobal/bb688134)
| 欢迎光临 北大中文论坛 www.pkucn.com (http://www.pkucn.com/) | Powered by Discuz! X2.5 |