Character encoding 如何解码加扰字符编码:特殊字符编码

Character encoding 如何解码加扰字符编码:特殊字符编码,character-encoding,non-ascii-characters,scramble,Character Encoding,Non Ascii Characters,Scramble,我有CSV格式的数据,这些数据在字符编码方面被严重打乱,可能在不同的软件应用程序(LibreOffice Calc、Microsoft、Excel、Google Refine、自定义PHP/MySQL软件;在世界不同地区的Windows XP、Windows 7和GNU/Linux机器上……)之间来回移动。似乎在这个过程中的某个地方,非ASCII字符被严重扰乱了,我不知道如何解扰或检测模式。手动执行此操作将涉及数千条记录 这里有一个例子。对于“Trois Rivières”,当我用Python打

我有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
回来

è

i、 我如何解读这个?一开始这怎么会变得混乱呢?如何对该错误进行反向工程?

您可以查看以下内容中提供的解决方案:

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

基于,我们可以猜测字母“è”不知何故被误解为“è”,然后对其应用了三重UTF-8编码

那么,“è”是如何变成“è”的呢?嗯,我有一种预感,最有可能的解释是在两个不同的8位字符集之间,所以我在维基百科上查找了一些,发现了一个匹配:在(以及其他各种相关的8位字符中,如CP851、CP853、CP857等)字母“è”被编码为字节0x8A,而在中代表“è”

有了这些知识,我们可以用一个简单的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字节进行编码。三代码> ICOV在中间调用重新创建应用于数据的实际重新编码步骤:首先从(假设)窗口1252到UTF-8,然后从ISO-859-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中表示的字节相同,在这种情况下,原则上应该可以进行反向转换。不过,我还没有想出如何说服
iconv
这样做。)

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