Dan*_*zar 7 unicode utf-16 case-folding
我正在尝试实现一个库来读取Microsoft CFB(复合文件二进制)格式文件,根据该格式的官方规范.该规范可从该站点获得.
简而言之 - 文件的某些结构存储在一个红黑树中.我在用于在该树中存储这些结构的比较谓词时遇到问题.规范说,如果这些结构的名称(字符串存储为UTF-16,Windows API中的标准)不同,则必须遍历每个UTF-16代码点,并且:
(...)使用Unicode默认大小写转换算法,简单大小写转换变体(简单大小写折叠)转换为大写,并带有以下注释.<2>比较每个大写的UTF-16代码点二进制值.
该<2>基准说:
或Windows XP和Windows Server 2003:复合文件实现符合Unicode 3.0.1默认大小写转换算法,简单案例折叠(http://www.unicode.org/Public/3.1-Update1/CaseFolding-4.txt)除以下例外.
然而,当我查阅引用的案例折叠文件,并阅读那里引用的UTR#21"案例映射"时,我意识到案例折叠被定义为一种与下套管更相似的操作,而不是上部 -套管.
通过使用CaseFolding-4.txt,我们可以获得大写字母到小写字母的大小写折叠映射.映射始终为1对1,因为此处不需要完全折叠(扩展为多个字符的折叠).但是,小写字母到大写字母的反向映射不再是直截了当的.例如,
0392; C; 03B2; # GREEK CAPITAL LETTER BETA
03D0; C; 03B2; # GREEK BETA SYMBOL
Run Code Online (Sandbox Code Playgroud)
因此,我们无法知道是否03B2应转换为0392或03D0.标准是否定义了折叠成大写的东西?也许我应该使用case折叠,然后转换为大写?或者我完全错误地理解了规范?
简介:微软使用的措辞至少令人困惑.似乎应该进行简单的大写映射,尽管我无法确定.
部分混淆可能是案例折叠和案例映射之间的区别.案例映射将每个字符映射到指定的案例.案例折叠虽然基于下套管,但被定义为导致无案例字符(UTR#21§1.3).
现在有两种不同的案例映射和案例折叠,简单和完整.与简单的转换不同,完整的转换可以改变字符串长度,正如你在这里不需要正确指出的那样.该规范明确提到了简单,可能是这个答案中唯一明确的事情.我觉得有必要提一下,为了将来的参考,当前的Unicode标准(6.3.0)提到默认的案例转换是完整的,尽管Microsoft引用的版本(3.1.1)似乎没有做出这种区分.
(...)使用Unicode默认大小写转换算法,简单大小写转换变体(简单大小写折叠)转换为大写,并带有以下注释.<2>比较每个大写的 UTF-16代码点二进制值.
对我来说这个引用似乎表明他们想要大写,并且简单地通过说案例折叠而不是案例映射来做出错误.但随后你引用了这个引用:
对于Windows XP和Windows Server 2003:复合文件实现符合Unicode 3.0.1默认大小写转换算法,简单案例折叠(http://www.unicode.org/Public/3.1-Update1/CaseFolding-4.txt)除以下例外.
他们实际上提到了案例折叠数据文件!在这一点上,我不确定该怎么想.我的主要思路是,微软希望机箱折叠虽然错误地认为它是基于上壳而不是下壳.这甚至是一个延伸,但它最接近我能够调和这个可能的矛盾,我希望有更好的解释.
我在第2.6.1节中发现以下内容支持某种形式的上壳:
[...]目录条目名称使用特殊的不区分大小写的大写映射进行比较,如Red-Black Tree中所述.
请注意,他们实际上在这里使用术语映射.
看一下上面提到的Windows XP和Windows Server 2003 的例外列表,大多数条目都是减法,这表明微软希望保持与众不同的代码点.但是,在表中,代码点实际上以与Unicode案例折叠数据文件相反的顺序列出.
对此的一种解释是它只是一个显示怪癖.这个想法被最后一行击落,它们减去了案例转换0x03C2 -> 0x03C2.这种转换在数据文件中不存在,因为转换0x03C2 -> 0x03C3确实存在(未列出的案例转换被认为是转换为自身).
另一种解释是,他们确实错误地认为它的反向映射是正确的.正如您所提到的,这会遇到麻烦,因为反向映射并不总是直截了当.否则,这种解释会没问题.
第三种解释是考虑他们对Unicode案例折叠数据文件的引用是错误的.这当然让我感到不安,但如果他们最初确实意味着案例映射,他们可能只是提供了链接作为快速参考点.他们提到的例外列表确实有列标题,例如"小写UTF-16代码点",但我们知道案例折叠实际上是无案例的.
顺便说一下,我确实查看了后续操作系统的例外列表,希望能够获得更多的洞察力.我发现更多的困惑.特别是0x03C3 -> 0x03A3麻烦我加了.由于异常列表和Unicode文件以相反的顺序列出它们的代码点,因此看起来转换已经在数据文件中而不需要添加.这部分规范不希望被理解!
如果您已经阅读了上述所有内容,您可能会猜测这个结论不太理想.显然,在一个或多个点上,规范是错误的,但很难分辨到哪里.实际上有三种可能性取决于您对需要进行何种案例转换的解释.
对我来说,似乎微软确实想要上壳.从那里我相信案例折叠参考是一个错误,因此我的猜测是他们只是想要简单的大写映射.
我非常怀疑这是最后一个简单的折叠选项.两个其他选项都会产生非常相似的结果,只有少量代码点可能会产生不同的结果.
似乎唯一可以确定的方法是联系微软,或者仔细查看二进制文件以了解遵循哪种方法.
| 归档时间: |
|
| 查看次数: |
1845 次 |
| 最近记录: |