如何编码和解码损坏的中文/Unicode字符?

6

我尝试过在谷歌上搜索,但无法找到以下文本所属的字符集:

具有éœé›»ç”¢ç”Ÿè£ç½®ä¹‹å½±åƒè¼¸å…¥è£ç½®

但是将<meta http-equiv="Content-Type" Content="text/html; charset=utf-8">放入HTML文件中并保留这个字符串,我就能够正确地查看中文字符了:

具有靜電產生裝置之影像輸入裝置 

所以我的问题是:

  1. 我可以使用哪些工具检测此文本的字符集?

  2. 我该如何在C#中正确地转换/编码/解码它们?

更新: 出于完整性考虑,我已更新此测试。

   [TestMethod]
    public void TestMethod1()
    {
        string encodedText = "具有éœé›»ç”¢ç”Ÿè£ç½®ä¹‹å½±åƒè¼¸å…¥è£ç½®";
        Encoding utf8 = new UTF8Encoding();
        Encoding window1252 = Encoding.GetEncoding("Windows-1252");

        byte[] postBytes = window1252.GetBytes(encodedText);
        
        string decodedText = utf8.GetString(postBytes);
        string actualText = "具有靜電產生裝置之影像輸入裝置";
        Assert.AreEqual(actualText, decodedText);
    }
}

可能是重复问题:https://dev59.com/n3VD5IYBdhLWcg3wGHiu。 - lesderid
你应该看一下这篇好文章:《绝对必须了解的Unicode和字符集知识(无任何借口!)》http://www.joelonsoftware.com/articles/Unicode.html - Dusan
如果你只有一串字节流,你无法检测它是否代表某种编码的文本。你必须由提供字节流的人告诉你。查看数据源的文档、手册和协议规范。 - Kerrek SB
我知道这一点,并且已经重新阅读了文档,但是如果是这种情况,为什么在浏览器中将字符集编码设置为UTF-8时字符可以正常显示呢?我在这里缺少哪些基本理解? - melaos
5个回答

9
当你使用声明正确编码方式的meta标签保存"bad"字符串到文本文件时,发生了什么是:你的文本编辑器将该文件保存为Windows-1252编码,但浏览器读取该文件时会将其解释为UTF-8。由于"bad"字符串是使用Windows-1252编码不正确解码的UTF-8字节,因此你会将该文件编码为Windows-1252并解码为UTF-8,这就相当于反转了该过程。
以下是示例:
using System.Text;
using System.Windows.Forms;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = "具有靜電產生裝置之影像輸入裝置"; // Unicode
            Encoding Windows1252 = Encoding.GetEncoding("Windows-1252");
            Encoding Utf8 = Encoding.UTF8;
            byte[] utf8Bytes = Utf8.GetBytes(s); // Unicode -> UTF-8
            string badDecode = Windows1252.GetString(utf8Bytes); // Mis-decode as Latin1
            MessageBox.Show(badDecode,"Mis-decoded");  // Shows your garbage string.
            string goodDecode = Utf8.GetString(utf8Bytes); // Correctly decode as UTF-8
            MessageBox.Show(goodDecode, "Correctly decoded");

            // Recovering from bad decode...
            byte[] originalBytes = Windows1252.GetBytes(badDecode);
            goodDecode = Utf8.GetString(originalBytes);
            MessageBox.Show(goodDecode, "Re-decoded");
        }
    }
}

即使进行了正确的解码,您仍然需要一个支持显示字符的字体。如果您的默认字体不支持中文,则可能无法看到正确的字符。
正确的做法是找出为什么您拥有的字符串首先被解码为Windows-1252。但有时,数据库中的数据存储本身就存在问题,您必须采取这些方法来解决问题。

哇!非常感谢,我一直想理解那些垃圾文本,终于你简单明了的解释太棒了!:) 是的,我相信最初的数据是以垃圾形式插入的...必须找到一种方法来清理它。 - melaos

1
string test = "敭畳灴獩楫n"; //incoming data. must be mesutpiskin 

byte[] bytes = Encoding.Unicode.GetBytes(test);

string s = string.Empty;

for (int i = 0; i < bytes.Length; i++)
{
    s += (char)bytes[i];
}

s = s.Trim((char)0);

MessageBox.Show(s);
//s=mesutpiskin 

0

我不太确定你的意思,但我猜你想在字符串和字节数组之间进行特定编码的转换。假设字符编码被称为“FooBar”:

这是编码和解码的方法:

Encoding myEncoding = Encoding.GetEncoding("FooBar");
string myString = "lala";
byte[] myEncodedBytes = myEncoding.GetBytes(myString);
string myDecodedString = myEncoding.GetString(myEncodedBytes);

您可以在MSDN上了解有关编码类的更多信息。


基本上,我想在C#中从第一个输入中获取第二个输出字符串,并且我知道如果我将字符集设置为UTF-8,记事本和Firefox可以做到这一点,我只是想了解如何在C#中完成它。清楚吗? - melaos
你从哪里获取输入字符串?是从文件、用户输入还是其他地方? - lesderid
通过LINQ to Entities从表列中提取数据。 - melaos

0

0

这是Windows Latin 1编码。我将UTF-8格式的中文文本粘贴到了BBEDIT(一款Mac上的文本编辑器)中,并以Windows Latin 1格式重新打开文件,结果完美地显示了重音符号。


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