【问题标题】:Strange utf8 decoding error in windows notepadWindows记事本中奇怪的utf8解码错误
【发布时间】:2019-04-15 13:31:52
【问题描述】:

如果你将下面的字符串输入到一个用utf8(不带bom)编码的文本文件中,然后用notepad.exe打开它,你会在屏幕上看到一些奇怪的字符。但是记事本实际上可以在没有最后一个'a'的情况下很好地解码这个字符串。非常奇怪的行为。我使用的是 Windows 10 1809。

[19, 16, 12, 14, 15, 15, 12, 17, 18, 15, 14, 15, 19, 13, 20, 18, 16, 19, 14, 16, 20, 16, 18, 12, 13, 14, 15, 20, 19, 17, 14, 17, 18, 16, 13, 12, 17, 14, 16, 13, 13, 12, 15, 20, 19, 15, 19, 13, 18, 19, 17, 14, 17, 18, 12, 15, 18, 12, 19, 15, 12, 19, 18, 12, 17, 20, 14, 16, 17, 18, 15, 12, 13, 19, 18, 17, 18, 14, 19, 18, 16, 15, 18, 17, 15, 15, 19, 16, 15, 14, 19, 13, 19, 15, 17, 16, 12, 12, 18, 12, 14, 12, 16, 19, 12, 19, 12, 17, 19, 20, 19, 17, 19, 20, 16, 19, 16, 19, 16, 12, 12, 18, 19, 17, 18, 16, 12, 17, 13, 18, 20, 19, 18, 20, 14, 16, 13, 12, 12, 14, 13, 19, 17, 20, 18, 15, 12, 15, 20, 14, 16, 15, 16, 19, 20, 20, 12, 17, 13, 20, 16, 20, 13a

我想知道这是否是一个 Windows 错误,或者我可以做些什么来解决这个问题。

【问题讨论】:

  • 似乎记事本将其解释为整个字符串的固定 2 字节,因此在内部将其转换为 UCS-2。 [1 9, 1 6, 1 2, 1 映射到 ㅛ ⰹ ㄠ ⰶ ㄠ ⰲ ㄠ ,所以第一个字符实际上是'[1',第二个是'9,',第三个是'1',等等。所以当你删除最后一个 'a',它不能将它编码为 2 字节字符。如果以上内容令人困惑,我很抱歉。我只懂点点滴滴。仍在试图弄清楚这一切。

标签: windows utf-8 character-encoding notepad


【解决方案1】:

做了更多的研究;想通了。

似乎是“布什隐瞒事实”经典案例的变体。 https://en.wikipedia.org/wiki/Bush_hid_the_facts

看起来记事本保存文件的字符编码默认值与打开文件的字符编码默认值不同。是的,这看起来确实是一个错误。

但是对于正在发生的事情有一个实际的解释:

  1. 记事本检查 BOM 字节序列。如果找不到,它有 2 个选项:编码是 UTF-16 Little Endian(无 BOM)或纯 ASCII。它首先使用名为 IsTextUnicode 的函数检查 UTF-16 LE。

  2. IsTextUnicode 运行一系列测试来猜测给定文本是否为 Unicode。其中一项测试是 IS_TEXT_UNICODE_STATISTICS,它使用统计分析。如果测试为真,则给定文本可能是 Unicode,但不能保证绝对确定性。
    https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-istextunicode

  3. 如果 IsTextUnicode 返回 true,记事本会使用 UTF-16 LE 对文件进行编码,从而产生您看到的奇怪输出。 我们可以用这个字符ㄠ来确认这一点。其对应的 ASCII 字符为 '1'(空格一);这些 ASCII 字符对应的十六进制值是空格的 0x20 和一的 0x31。由于字节顺序是 Little Endian,Unicode 码位的顺序是 '1' 或 U+3120,您可以通过查找该码位来确认。
    https://unicode-table.com/en/3120/

如果你想解决这个问题,你需要打破有助于 IsTextUnicode 确定给定文本是否为 Unicode 的模式。您可以在文本前插入换行符以打破模式。

希望有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多