【问题标题】:How to Decode Scrambled Character Encoding: Special Character Encoding如何解码加扰字符编码:特殊字符编码
【发布时间】:2012-01-02 22:44:56
【问题描述】:

我有 CSV 格式的数据,这些数据经过了严重的字符编码处理,可能在不同的软件应用程序(LibreOffice Calc、Microsoft、Excel、Google Refine、自定义 PHP/MySQL 软件;在 Windows XP、Windows 7 上)之间来回切换和来自世界各地的 GNU/Linux 机器......)。似乎在这个过程中的某个地方,非 ASCII 字符已被严重扰乱,我不确定如何解扰它们或检测模式。手动执行此操作将涉及数千条记录...

这是一个例子。对于“Trois-Rivières”,当我用 Python 打开这部分 CSV 文件时,它说:

Trois-Rivi\xc3\x83\xc2\x85\xc3\x82\xc2\xa0res

问题:我可以通过什么过程来逆转

\xc3\x83\xc2\x85\xc3\x82\xc2\xa0

回来

è

即我怎样才能解读这个?这怎么可能一开始就被打乱了?如何对这个 bug 进行逆向工程?

【问题讨论】:

  • 它看起来像 utf8 over iso over utf8... 也许你应该试试iconv
  • 我怀疑 \xc3\x83\xc2\x85\xc3\x82\xc2\xa0 转换为单个 è
  • echo -e 'Trois-Rivi\xc3\x83\xc2\x85\xc3\x82\xc2\xa0res' | file -: /dev/stdin: UTF-8 Unicode 文本,带有 LF、NEL 行终止符
  • 它看起来已经损坏无法修复(可能是由于在此之前的错误字符集转换)。我看不出比 utf8 更理智的解释,但即使那样它看起来也已经损坏了
  • 在将 double UTF-8 误解为 ISO-8859-1 之后,它看起来像 UTF-8,但是以这种方式解码它会得到 U+0160 (Š) 而不是预期 U+00E8 (è)。

标签: character-encoding non-ascii-characters scramble


【解决方案1】:

您可以查看提供的解决方案:Double-decoding unicode in python

另一个更简单的蛮力解决方案是在输入文件上使用正则表达式(((\\\x[a-c0-9]{2}){8})) 搜索在一小部分加扰字符之间创建一个映射表。对于单一来源的文件,法语应少于 32 个,德语应少于 10 个。然后您可以使用这个小映射表运行“查找和替换”。

【讨论】:

    【解决方案2】:

    根据dan04's comment above,我们可以猜测字母“è”不知何故被误解为“Š”,然后对其应用了三重 UTF-8 编码。

    那么“è”是如何变成“Š”的呢?好吧,我有一种预感,最有可能的解释是在两个不同的 8 位字符集之间,所以我在 Wikipedia 上查找了一些 common character encodings,并找到了一个匹配项:在 CP850 中(以及其他各种相关的 8 位字符集) DOS code pages,如CP851、CP853、CP857等)字母“è”编码为字节0x8A,在Windows-1252中代表“Š”。

    有了这些知识,我们可以用一个简单的 Unix shell 命令行重新创建这个曲折的错误编码链:

    $ echo "Trois-Rivières" \
      | iconv -t cp850 \
      | iconv -f windows-1252 -t utf-8 \
      | iconv -f iso-8859-1 -t utf-8 \
      | iconv -f iso-8859-1 -t utf-8 \
      | iconv -f ascii --byte-subst='\x%02X'
    
    Trois-Rivi\xC3\x83\xC2\x85\xC3\x82\xC2\xA0res
    

    在这里,第一个 iconv 调用只是将字符串从我的本地字符编码(恰好是 UTF-8)转换为 CP850,最后一个只是使用 Python 样式的 \xNN 编码非 ASCII 字节转义码。中间的三个iconv 调用重新创建应用于数据的实际重新编码步骤:首先从(假定的)Windows-1252 到 UTF-8,然后从 ISO-8859-1 两次转为 UTF-8。

    那么我们该如何解决呢?好吧,我们只需要反向应用相同的步骤:

    $ echo -e 'Trois-Rivi\xC3\x83\xC2\x85\xC3\x82\xC2\xA0res' \
      | iconv -f utf-8 -t iso-8859-1 \
      | iconv -f utf-8 -t iso-8859-1 \
      | iconv -f utf-8 -t windows-1252 \
      | iconv -f cp850
    
    Trois-Rivières
    

    好消息是这个过程应该大部分是可逆的。坏消息是原始文本中的任何“ü”、“ì”、“Å”、“É”和“Ø”字母都可能被不可逆转地损坏,因为在 CP850 中用于编码这些字母的字节在 Windows 中是未定义的-1252。 (如果幸运的话,它们可能被解释为那些字节在 ISO-8859-1 中表示的 C1 control codes,在这种情况下,原则上应该可以进行反向转换。我还没有弄清楚如何不过,要说服 iconv 去做。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 2011-12-28
      • 2016-10-19
      • 1970-01-01
      相关资源
      最近更新 更多