引自here:
安全性也可能受到多个角色特征的影响 编码,包括UTF-8:“同样的事情”(就用户而言) tell)可以用几个不同的字符序列表示。对于 例如,具有强烈重音的e可以由预组合表示 U + 00E9 E ACUTE字符或标准等效序列 U + 0065 U + 0301(E + COMBINING ACUTE)。尽管UTF-8提供了一个 每个字符序列的单字节序列,存在 “同一件事”的多个字符序列可能具有安全性 字符串匹配,索引,
的后果
这是我以前从未解决过的UTF-8的隐藏功能吗?
答案 0 :(得分:5)
这个问题实际上并不特定于UTF-8。所有编码都可以代表所有(或至少大多数)Unicode代码点。
Unicode的一般理念是不提供所谓的pre-composed characters(例如U+00E9 E ACUTE),而不是他们通常喜欢提供基本字符(例如U+0065 LATIN SMALL LETTER E)和组合字符(例如U+0301 COMBINING ACUTE ACCENT)。这样做的好处是不必将所有可能的组合作为自己的特征。
注意:the U+xxxx notation is used to refer to unicode codepoints。它是与编码无关的引用Unicode字符的方式。
然而首次设计Unicode时,一个重要的目标是为现有的,广泛使用的编码提供往返兼容性,因此包含一些预先组成的字符(事实上,包括拉丁语和相关字母的大多数变音符号。)
所以是的(以及 tl; dr ):在正确运行的支持Unicode的应用程序中,U + 00E9的呈现方式与和的处理方式相同+0065,然后是U + 0301。
有一个名为normalization的非平凡过程可以通过将给定字符串减少为四种常规形式之一来帮助处理这些差异。
例如,在使用NFC时传递两个字符串(U+00E9
和U+0065 U+0301
)将导致U+00E9
,并且在使用NFD时会产生U+0065 U+0301
。
答案 1 :(得分:3)
非常简短且可视化的示例:字符“é”可以使用Unicode代码点U + 00E9(LATIN SMALL LETTER E WITH ACUTE,é
)或序列U + 0065(LATIN SMALL)表示字母E,e
)后跟U + 0301(COMBINING ACUTE ACCENT,´
),它们一起显示如下:é
。
在UTF-8中,é
具有字节序列xC3 xA9
,而é
具有字节序列x65 xCC x81
。
注意:由于技术限制,此帖子不包含实际的组合字符。
答案 2 :(得分:1)
其实我不明白这是什么意思:
“即使UTF-8为每个字符提供单字节序列 序列[...]“
引用想说的是:
“任何给定的Unicode代码点序列都通过UTF-8编码映射到一个(并且恰好是一个)字节序列。”也就是说,UTF-8是(抽象的)Unicode代码点和字节序列之间的双射。
文本想要说明的问题是,“文本字母”(通常理解的)和Unicode代码点之间存在 no 双射,因为可以表示相同的文本通过不同的Unicode代码点序列(如示例中所述)。
实际上,这与UTF-8没有任何关系;它是Unicode的基本属性:许多文本都有多个表示作为Unicode代码点。在比较以Unicode表示的文本时(无论采用何种编码方式),请务必牢记这一点。
对此的一个(部分)解决方案是normalization。它为Unicode文本定义了各种 Normal表单,它们是文本的唯一表示。