【问题标题】:Why is the following string comparison code returning TRUE after appending 0x81为什么以下字符串比较代码在附加 0x81 后返回 TRUE
【发布时间】:2023-03-27 16:10:02
【问题描述】:

以下代码是一种解决方法,它允许我们使用现有产品中的某些功能,而无需更改其中的任何代码。这对我们来说是件好事,但我想了解为什么会这样? 0x81 字符有什么特别之处?

"A".Equals(Encoding.UTF8.GetString(new byte[] { 0x41, 0x81 }), StringComparison.InvariantCulture) // Returns TRUE

以上代码适用于 CurrentCulture 和 InvariantCulture 但不适用于 Ordinal。这是有道理的,因为按顺序比较每个字节都会在上面的代码中失败。它不适用于默认编码 (SBCS)。

【问题讨论】:

    标签: c# .net string encoding string-comparison


    【解决方案1】:

    字节序列 { 0x41, 0x81 } 不是有效的 UTF-8,因为字节 0x41 本身代表“A”字符,字节 0x81 不能出现在 UTF-8 编码序列的开头,并且是这个位置有错误。

    由于 Encoding.UTF8.GetString() 没有抛出异常,它可能会在字符串中添加替换字符 (U+FFFD),如 MSDN 上的choosing a fallback strategy 中所述。

    所以你可能在比较字符串“A”和字符串“A”+替换字符,有些字符串比较可能会忽略替换字符,从而返回true。

    【讨论】:

    • 好的。这是一个可以在即将发布的版本中修复的“忽略替换字符”的错误吗?如果我获取字符串并在其上调用 UTF8.GetBytes(...),那么我会得到这四个字节:65、239、191、189。
    • 对,65 是 0x41,所以这就是“A”。剩下的三个字节是 U+FFFD 的 UTF-8 编码,即添加到字符串中的替换字符,以响应在输入中看到原始无效的 0x81 字节。这不是 Encoding.UTF8 中的错误,这是一件完全合理的事情。您可以将其配置为按照 MSDN 中所述的不同行为,但您可能需要首先弄清楚您要做什么:)
    • @A9S6 如果你期待 UTF-8,你应该已经在你得到0x81 的地方失败了,并从源请求有效的 UTF-8。公共 Web 服务器可以从任意客户端接收任意字节,并且不应尝试处理它,因为合法的浏览器客户端总是发送有效的 UTF-8。但是配置错误的替代客户端或恶意请求可能会发送无效的 UTF-8。
    【解决方案2】:

    您只需删除文化信息,它就可以正常工作, 即使用 "A".Equals(Encoding.UTF8.GetString(new byte[] { 0x41, 0x81 })) 代替 "A".Equals(Encoding.UTF8.GetString(new byte[] { 0x41, 0x81 }), StringComparison.InvariantCulture)

    【讨论】:

      猜你喜欢
      • 2012-04-12
      • 2019-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 1970-01-01
      • 2020-04-29
      相关资源
      最近更新 更多