这个坏的字符编码问题可能是由什么原因引起的?

5
什么“堆栈”错误编码会导致字符串“cinéma télédiffusion”产生以下奇怪的字节?(我省略了空格字符,十六进制:20)
cinÃ%ma
in HEX: 63 69 6E C3 83 25 6D 61
mapped: c  i  n  ---�----  m  a

tÃclÃcdiffusion
in HEX: 74 C3 83 63 6C C3 83 63 64 69 66 66 75 73 69 6F 6E
mapped: t  ---�---- l  ---�---- d  i  f  f  u  s  i  o  n

---�---- 部分代表了不正确的字节。

我考虑了这个想法:“如果是混乱的转码怎么办?双重编码呢?”但是,查看 http://www.fileformat.info/info/unicode/char/00e9/charset_support.htm(以及代码页版本),我注意到没有编码可能以十六进制字节%25或%63结束é。此时它甚至看起来不像是双重UTF8编码,因为 http://en.wikipedia.org/wiki/UTF-8 澄清了跟随%C3的字节需要将第一个位设置为10xxxxxx。

某个程序如何将带重音的 é 变成" Ã 后面跟着%"以及" Ã 后面跟着c"?我想追溯误编码的历史,以便尝试提出一些可以采取步骤修复损坏字符串的东西。

也有可能这些é从一开始就不是é,但我无法理解在相同的短语中出现两个不同版本的é的打字错误可能会是什么,最终被编码成完全不同的字节集。
额外的上下文细节:我在一个XML文件中发现了这些混乱的字符串。该文件没有<?xml version="1.0"?>头,因此被认为是UTF-8。存在包含完全正确的é字符的节点,同时也存在包含混乱的é字符的短语节点。 iconv等工具对于解决这种情况毫无作用,至少我尝试了没有效果。
我现在考虑的几点是:我应该怀疑MySQL及其臭名昭著的懒惰字符集转换吗?这可能是某个人编写的非常糟糕的自定义编码函数,因为他们导出XML吗?

3
它明显被utf-8编码了两次。之间还有一个神秘的代码页编码。这些编码不同。其中一个把©变成了c。另一个很难猜测。把那个XML文件发回来,你不需要它。 - Hans Passant
同一个字符在不同的单词中转换成了不同的字节,这很奇怪。 - dan04
是的,我认为这永远不可能被恢复了。很抱歉!肯定有一个双重UTF-8存在,但是非确定性的混淆会在第二个字符处输出ASCII,这既不是常见的也不是可纠正的损坏。 - bobince
这些见解带来了清晰度,我很感激。我最初的意思是“它看起来不像-通常可恢复的-双重UTF8编码”。我喜欢那个时髦的双重编码被描述为“把那个xml文件发回去,你不想要它。” :) 从技术上讲,我觉得我的问题已经得到了回答...不知道该怎么处理空的“答案”部分。 - starlocke
1个回答

1

编码看起来有点奇怪:

从cinéma中取出é的utf-8编码为:

é = C3 A9

而你得到的是:

C3 83 25

所以当它被双重编码时,应该会发生以下情况:

c3: Ã -> c3 83

a9: © -> c2 a9

但这不能解释结果中的25。

25: %

因此问题是,如果这是一次编码,那么未知字符如©将被替换为%,然后再进行第二次编码吗?


两个单词的整个字符串在重音符“e”周围以不同的方式被搞乱了。在每种“搞乱”的情况下,都出现了额外的字符:“%”(十六进制25)在第一种情况下,“c”(十六进制63)在后两种情况下。我认为双重编码、代码页和编码丢失的确切堆栈将在相当长的时间内保持不变。我怀疑这些字节在MySQL的“ASCII、3字节UTF8和完整UTF8”方案以及各种编程语言的“ASCII和UTF8”字符串之间被破坏了。 - starlocke
仅供参考:UTF-8是(根据使用的字符)始终为1-4字节编码。因此,没有3字节的UTF-8与“完整”的UTF-8相比较 - 更多信息请参见https://en.wikipedia.org/wiki/UTF-8 另外,从我上面的例子中,我并没有看到在é的双重编码过程中出现任何有效的UTF-8 3字节代码。因此,必须有其他更多的东西除了双重编码。另外还有一件奇怪的事情是,对于cinéma和télédiffusion,é会产生不同的字节。 - PowerStat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接