【问题标题】:Anyone can explain the "same thing" issue of UTF-8?任何人都可以解释 UTF-8 的“同一件事”问题吗?
【发布时间】:2011-12-04 08:34:53
【问题描述】:

引用自here

安全性也可能受到几个字符的特性的影响 编码,包括 UTF-8:“相同的东西”(就用户而言 tell) 可以由几个不同的字符序列表示。为了 例如,带有重音的 e 可以由预先组合的 U+00E9 E ACUTE 字符或规范等效序列 U+0065 U+0301(E + 合并急性)。尽管 UTF-8 提供了 每个字符序列的单字节序列,存在 “同一事物”的多个字符序列可能具有安全性 每当字符串匹配、索引时的后果,

这是我以前从未处理过的 UTF-8 的隐藏特性吗?

【问题讨论】:

  • 我不明白你的问题......你发布的报价说明了一切 - 因为 Unicode(它是 UTF8 的基础,只是一种编码)支持多个字符集等渲染的字符从用户的角度来看,两个不同的 unicode 代码点可能是相同的......这可能会以影响安全的方式被滥用......
  • @Yahia,只要只使用 ONE 编码,这不是问题,也许您可​​以详细说明您的意思是什么?
  • 我不认为我们在谈论同一件事......编码和字符集是非常不同的东西......你所说的对于字符集可能是正确的,但绝对是错误的关于编码...

标签: unicode utf-8


【解决方案1】:

非常简短且可视化的示例:字符“é”可以使用 Unicode 代码点 U+00E9(带尖音的拉丁小写字母 E,é)或序列 U+0065(拉丁小写字母 E)来表示, e) 后跟 U+0301(组合重音,´),它们一起看起来像这样:é

在 UTF-8 中,é 的字节序列为 xC3 xA9,而é 的字节序列为 x65 xCC x81

注意:由于技术限制,本文不包含实际的组合字符。

【讨论】:

  • 取决于您使用的编码。使用您选择的语言编写 "\xC3\xA9""\x65\xCC\x81" 可能会也可能不会成功。或者在 Mac OS X 上,您可以使用一个字符调色板来选择这些单独的字符...
  • gbk、euc-jp等其他多字节字符编码是否存在此类问题?
  • 我不知道其他具有 combining 变音符号等概念的编码,但是我还没有研究过大多数其他编码就像我有 Unicode 一样。所以,我不能肯定。
【解决方案2】:

这个问题实际上根本不是 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 应该以相同的方式呈现 并且与 U 的处理方式相同+0065 后跟 U+0301。

有一个名为normalization 的重要过程通过将给定字符串减少为四种范式之一来帮助处理这些差异。

例如,传递两个字符串(U+00E9U+0065 U+0301)在使用 NFC 时将导致 U+00E9,在使用 NFD 时将导致 U+0065 U+0301

【讨论】:

  • 什么是U+00E9 E ACUTEU+0301 COMBINING ACUTE ACCENT
  • @new_perl:我已经在我的回答中解释了 U+xxxx 符号。另外:您可能大量使用了预编字符,因为它们几乎无处不在(尽管 Unicode 联盟试图摆脱它们)。
  • 我刚刚看了en.wikipedia.org/wiki/Precomposed_character,但是U+00C5 U+0073 U+0074 U+0072 U+00F6 U+006DU+0041 U+030A U+0073 U+0074 U+0072 U+006F U+0308 U+006D不一样,只是相似,重音的位置不同……
  • @new_perl:它们不一样,因为文章通过尝试将合成字符与基本字符不同的颜色来有效地禁用合成。这 可能 在某些浏览器上正确呈现,但我怀疑它是否符合标准。这是文章中的一个不幸的错误,应该纠正。除此之外,您可能使用的浏览器支持不完美的合成。
  • 我刚刚验证了它:在当前的 Firefox 上它确实正确呈现,即使字符颜色不同。
【解决方案3】:

其实我不明白这是什么意思:

"尽管 UTF-8 为每个字符提供了一个单字节序列 序列[...]"

这句话想说的是:

“任何给定的 Unicode 代码点序列都通过 UTF-8 编码映射到一个(并且恰好是一个)字节序列。”也就是说,UTF-8 是(抽象)Unicode 代码点和字节序列之间的双射。

文本想要说明的问题是,“文本的字母”(通常理解)和 Unicode 代码点之间没有双射,因为可以表示相同的文本通过不同的 Unicode 代码点序列(如示例中所述)。

其实这和 UTF-8 没有什么特别的关系;它是 Unicode 的一个基本属性:许多文本有多个表示为 Unicode 代码点。在比较以 Unicode 表示的文本(无论采用何种编码)时,请牢记这一点。

对此的一个(部分)解决方案是normalization。它为 Unicode 文本定义了各种标准形式,它们是文本的唯一表示。

【讨论】:

  • @new_perl:有关组成的信息包含在官方的“Unicode 字符数据库”(unicode.org/ucd)中。我不知道是否有一种简单的方法可以提取预先组合的字符列表。
  • 为什么到目前为止我从来没有遇到过这类问题?操作系统已经处理了吗?
  • @new_perl:您是否遇到问题取决于您的操作。如果您从不使用预组合字符(或始终使用它们),则比较很容易。
猜你喜欢
  • 2011-03-31
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多