【问题标题】:Is there a way to tell a text (csv) file has been converted or processed using wrong encoding?有没有办法告诉文本(csv)文件已使用错误的编码进行转换或处理?
【发布时间】:2014-07-05 19:37:34
【问题描述】:

对不起,标题有点含糊,我想不出更好的。一旦想到更好的标题,我会立即对其进行编辑。

问题如下:

  1. 我的系统在UTF-8中导出一个CSV文件
  2. 用户在他的编辑器中打开文件 - 可能是 UTF,也可能是其他字符集 - 例如,Windows-1250(但实际上可以是任何字符集)
  3. 用户将文件保存在UTF-8 *
  4. 用户将文件导入回系统,现在所有的重音符号和特殊字符都变成了乱码。

编辑:编码问题可能发生也可能不发生!另外,我不知道哪个字符集可能已被“用于”不需要的转换。

问题是:

有没有办法判断在流程的任何一个步骤中编码是否被错误解释或更改?

我不需要其他任何东西,只是为了警告用户 utd-8 字符集在进程的一个步骤中被误解了,或者文件由于字符集转换而被损坏..

另外,我不需要任何防黑客的解决方案,我只想减轻施加在用户身上的负担,以便在发生潜在的灾难性情况时向他们发出警告。


详情:

我在这里处理的是 CSV,我没有看到任何简单的方法来隐藏控制字符,以便用户不会偶然或故意删除它。

使用的编辑器种类繁多,主要是德语的 MS Excel,但不幸的是,它不仅限于此。可以导出 Unicode (UTF-16 LE) 文本文件,但这并不能解决问题 - 由于(无意的)字符集操作,上传的文件的 Unicode 格式错误。

我想出的解决方案是,我将始终在第一行显示® Company Inc. - Do not remove this line 之类的内容,其中 (R) 符号是控制字符 - 很容易检查它是否是预期的字符或不是。但我相信你会同意,这离一个好的解决方案还差得很远。

【问题讨论】:

    标签: csv unicode utf-8 character-encoding


    【解决方案1】:

    如果您知道他们使用的编码(在本例中为 CP1250,虽然德语 Excel 宁愿指示 CP1252),您可以尝试撤消更改并查看是否出现有效的 UTF-8,即:

    1. 以 UTF-8 格式读取文件
    2. 转换为 CP1250
    3. 再次将字节解释为 UTF-8

    如果第 3 步有错误,那么文件显然是 UTF-8 开头的(至少错误概率可以忽略不计),如果不是,那么您所描述的就发生了。

    额外的好处:如果数据是 ASCII 格式,这将不会破坏任何内容。

    快速 PowerShell 测试:

    PS Home:\> $s = '® Company Inc. - Do not remove this line'
    PS Home:\> $bytesInFile = [System.Text.Encoding]::UTF8.GetBytes($s)
    PS Home:\> $wrongText = [System.Text.Encoding]::GetEncoding(1250).GetString($bytesInFile)
    PS Home:\> $wrongText
    ® Company Inc. - Do not remove this line
    PS Home:\> $wrongBytes = [System.Text.Encoding]::UTF8.GetBytes($wrongText)
    
    PS Home:\> # 1. read as UTF-8
    PS Home:\> $readString = [System.Text.Encoding]::UTF8.getString($wrongBytes)
    PS Home:\> # 2. Convert to CP1250
    PS Home:\> $readStringAs1250Bytes = [System.Text.Encoding]::GetEncoding(1250).GetBytes($readString)
    PS Home:\> # 3. Interpret as UTF8 again
    PS Home:\> $interpretedText = [System.Text.Encoding]::UTF8.getString($readStringAs1250Bytes)
    PS Home:\> $interpretedText
    ® Company Inc. - Do not remove this line
    

    如果文件没有损坏:

    PS Home:\> # 1. read as UTF-8
    PS Home:\> $readString = [System.Text.Encoding]::UTF8.getString($bytesInFile)
    PS Home:\> # 2. Convert to CP1250
    PS Home:\> $readStringAs1250Bytes = [System.Text.Encoding]::GetEncoding(1250).GetBytes($readString)
    PS Home:\> # 3. Interpret as UTF8 again
    PS Home:\> $interpretedText = [System.Text.Encoding]::UTF8.getString($readStringAs1250Bytes)
    PS Home:\> $interpretedText
    � Company Inc. - Do not remove this line
    PS Home:\> $interpretedText.Contains([char]0xFFFD)
    True
    

    最安全的方法可能是告诉编码/解码器在无效字符上抛出错误,但这在一定程度上取决于您使用的是什么。不过,通常您可以设置它(我只是不精通 .NET 的那一部分,无法通过 PowerShell 进行设置)。检查 U+FFFD 替换字符将是下一个最佳选择。

    【讨论】:

    • 感谢您非常详细的回答!看起来我需要编辑我的问题 - 完全不确定是否发生了到 CP1250 的转换,或者用于 malencoding 的代码页 used 是否确实是 CP1250 或其他一些。我需要的只是检测,我真的不想用任何更正来打扰服务器,这取决于用户。
    • +1 我现在编辑了这个问题,以更好地强调我需要什么。如果没有更好的解决方案,您对 BOM 和检查转换错误的建议似乎是可行的!
    • 我根本没有提到 BOM。只是在 8 位代码页中解释已经是 UTF-8 的文本,然后再次解释为 UTF-8 将非常非常可能会乱码非 ASCII 字符 - 但以可预测的方式(解码器抛出错误或插入 U +FFFD)。因此,如果文件编码没有被篡改,那么上面那个小小的转换舞会产生错误。如果是这样,那么你会得到一些最明智的东西。但即使您不知道可能使用不当的编码,您仍然可以检测到错误,但不会自动更正。
    • 是的,我现在明白了(我误读了 BOM 的 FFFD,抱歉)。从概念上讲,这就是我所带来的,我真的很喜欢将其转换回来的可能性。但如果可能的话,如果可能的话,我想完全避免第一行。我想不出比这更明智的方法了,所以如果几天后没有更好的情况出现,我会将您的答案标记为已接受。非常感谢!
    猜你喜欢
    • 2012-01-26
    • 2020-07-12
    • 1970-01-01
    • 2021-01-13
    • 2013-08-31
    • 2019-03-31
    • 2013-10-13
    • 1970-01-01
    • 2011-07-28
    相关资源
    最近更新 更多