C#:在shift-JIS中转换日文文本编码并以ASCII格式存储为UTF-8

时间:2013-11-12 01:47:54

标签: c# encoding

我正在尝试将存储在数据库中的某些字符串的旧应用程序转换为ASCII。

例如,字符串:ƒ`ƒƒƒlƒ<ƒp[ƒgƒi[,Ì'I'ð]存储在数据库中。

现在,如果我在文本编辑器中复制该字符串并将其保存为ASCII,然后在Web浏览器中打开该文件并将其设置为自动检测编码,我会在日语中找到正确的字符串:チャネルパートナーの选択,并且页面显示检测到的编码是日语(Shift_JIS)。

当我尝试在C#代码中进行转换时,执行以下操作:

var asciiBytes = Encoding.ASCII.GetBytes(text);
var japaneseEncoding = Encoding.GetEncoding(932);
var convertedBytes = Encoding.Convert(japaneseEncoding, Encoding.ASCII, asciiBytes);
var japaneseString = japaneseEncoding.GetString(convertedBytes);

我明白了?`??? ???????????????????作为日语字符串,因此我无法在网页上显示它。

任何光都会受到赞赏。

由于

3 个答案:

答案 0 :(得分:9)

  

某些字符串以ASCII格式存储在数据库中

它不是ASCII,关于ƒ`ƒƒƒlƒ中没有任何字符[ƒgƒi[,Ì'I'ð是ASCII。 Encoding.ASCII.GetBytes(text)会产生很多吧?字符,这就是你得到所有这些问号的原因。

核心问题是dbase列中的字节是使用错误的编码读取的。您使用了代码页1252:

var badstringFromDatabase = "ƒ`ƒƒƒlƒ‹ƒp[ƒgƒi[‚Ì‘I‘ð";
var hopefullyRecovered = Encoding.GetEncoding(1252).GetBytes(badstringFromDatabase);
var oughtToBeJapanese = Encoding.GetEncoding(932).GetString(hopefullyRecovered);

产生“チャネルパートナーの选択”

这不是完全可靠的,代码页1252有一些在932中使用的未分配代码。您将最终得到一个乱码字符串,您无法再恢复原始字节值。您需要专注于让数据提供者使用正确的编码。

答案 1 :(得分:3)

根据另一个答案,我很确定你使用的是ANSI /默认编码而不是ASCII。

以下示例似乎可以帮助您了解您的目标。

var japaneseEncoding = Encoding.GetEncoding(932);

// From file bytes
var fileBytes = File.ReadAllBytes(@"C:\temp\test.html");
var japaneseTextFromFile = japaneseEncoding.GetString(fileBytes);
japaneseTextFromFile.Dump();

// From string bytes
var textString = "ƒ`ƒƒƒlƒ‹ƒp[ƒgƒi[‚Ì‘I‘ð";
var textBytes = Encoding.Default.GetBytes(textString);
var japaneseTextFromString = japaneseEncoding.GetString(textBytes);
japaneseTextFromString.Dump();

有趣的是,我认为我需要阅读Encoding.Convert因为它没有产生我预期的行为。 GetString方法似乎只有在传入以Encoding.Default格式读取的字节时才会起作用 - 如果我事先转换为日语编码,则它们无法按预期工作。

答案 2 :(得分:0)

此代码将转储许多不同的选项,以便您可以看到即将结束的内容。 在没有任何编码意识的旧应用程序中,我经常使用它作为注释。

您可以在此处复制粘贴以在线运行它: https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding.getencodings?view=netframework-4.8#System_Text_Encoding_GetEncodings

using System;

public class Program
{
    public static void Main()
    {
        var badstringFromDatabase = "ƒ`ƒƒƒlƒ‹ƒp[ƒgƒi[‚Ì‘I‘ð";
        var recovered1 = System.Text.Encoding.GetEncoding(932).GetBytes(badstringFromDatabase); //Shift JIS
        var recovered2 = System.Text.Encoding.GetEncoding(20932).GetBytes(badstringFromDatabase); //EUC
        var recovered3 = System.Text.Encoding.GetEncoding(51932).GetBytes(badstringFromDatabase); //EUC
        var recovered4 = System.Text.Encoding.GetEncoding(50220).GetBytes(badstringFromDatabase); //ISO-2022-JP
        var recovered5 = System.Text.Encoding.GetEncoding(50221).GetBytes(badstringFromDatabase); //ISO-2022-JP
        var recovered6 = System.Text.Encoding.GetEncoding(50222).GetBytes(badstringFromDatabase); //ISO-2022-JP
        var recovered7 = System.Text.Encoding.GetEncoding(65001).GetBytes(badstringFromDatabase); //UTF-8
        var recovered8 = System.Text.Encoding.GetEncoding(1200).GetBytes(badstringFromDatabase); //UTF-16
        var recovered9 = System.Text.Encoding.GetEncoding(12000).GetBytes(badstringFromDatabase); //UTF-32
        var recovered10 = System.Text.Encoding.GetEncoding(12001).GetBytes(badstringFromDatabase); //UTF-32BE
        var recovered11 = System.Text.Encoding.GetEncoding(65000).GetBytes(badstringFromDatabase); //UTF-7
        Console.WriteLine("Shift JIS: " + System.Text.Encoding.GetEncoding(932).GetString(recovered1)); //Shift JIS
        Console.WriteLine("EUC: " + System.Text.Encoding.GetEncoding(932).GetString(recovered2)); //EUC
        Console.WriteLine("EUC: " + System.Text.Encoding.GetEncoding(932).GetString(recovered3)); //EUC
        Console.WriteLine("ISO-2022-JP: " + System.Text.Encoding.GetEncoding(932).GetString(recovered4)); //ISO-2022-JP
        Console.WriteLine("ISO-2022-JP: " + System.Text.Encoding.GetEncoding(932).GetString(recovered5)); //ISO-2022-JP
        Console.WriteLine("ISO-2022-JP: " + System.Text.Encoding.GetEncoding(932).GetString(recovered6)); //ISO-2022-JP
        Console.WriteLine("UTF-8: " + System.Text.Encoding.GetEncoding(932).GetString(recovered7)); //UTF-8
        Console.WriteLine("UTF-16: " + System.Text.Encoding.GetEncoding(932).GetString(recovered8)); //UTF-16
        Console.WriteLine("UTF-32: " + System.Text.Encoding.GetEncoding(932).GetString(recovered9)); //UTF-32
        Console.WriteLine("UTF-32BE: " + System.Text.Encoding.GetEncoding(932).GetString(recovered10)); //UTF-32BE
        Console.WriteLine("UTF-7: " + System.Text.Encoding.GetEncoding(932).GetString(recovered11)); //UTF-7
    }
}