gpt4 book ai didi

c# - 如何将数据库中存储在 ANSI (Windows 1252) 中的值转换为 UTF-8

转载 作者:行者123 更新时间:2023-11-30 16:05:52 31 4
gpt4 key购买 nike

当我在 Sqlite Browser 中打开遗留数据库时,文本已经显示错误。我可以设置的唯一编码是 UTF-8 和 UTF-16。
Sqlite browser with Umlaut

当我查询数据库时,Visual Studio 中的编码已经是错误的。
Visual Studio locals

我假设文本是用 ANSI (Windows-1252) 编码的(在评论中确认)。我尝试将其转换为 UTF-8

        var encoding = Encoding.GetEncoding(1252);
byte[] encBytes = encoding.GetBytes(result);
byte[] utf8Bytes = Encoding.Convert(encoding, Encoding.UTF8, encBytes);
return Encoding.UTF8.GetString(utf8Bytes);

但现在问号符号只是一个问号。
Still wrong

不知何故,外部遗留应用程序正确显示它,所以似乎有办法。但我不确定接下来可以尝试什么。

最佳答案

我遇到过同样的问题,

John Skeet 回答了它 here :

基本上获取字符串,获取其编码错误编码中的字节,然后获取其实际编码中的字符串:

string broken = "Brokers México, Intermediario de Aseguro,S.A."; // Get text from database
byte[] encoded = Encoding.GetEncoding(28591).GetBytes(broken);
string corrected = Encoding.UTF8.GetString(encoded);

所以你的应该是

string broken = "Whatever";
byte[] encoded = Encoding.GetEncoding(1252).GetBytes(broken);
string corrected = Encoding.UTF8.GetString(encoded);

基本上,既然您知道重新转换程序是正确的,我会尝试使用这里提到的编码:
https://msdn.microsoft.com/en-us/library/system.text.encodinginfo.getencoding(v=vs.110).aspx
(只需编写一个程序来测试那里列出的所有可能的可能性,然后看看哪对会产生匹配...)

如果您知道源文本,您甚至可以自动执行检查:

public partial class Form1 : Form
{
public System.Data.DataTable dt;

public Form1()
{
InitializeComponent();
}




private void btnTest_Click(object sender, EventArgs e)
{
dt = new System.Data.DataTable();

string correct = "Brokers México, Intermediario de Aseguro,S.A.";

string broken = "Brokers México, Intermediario de Aseguro,S.A."; // Get text from database

dt.Columns.Add("SourceEncoding", typeof(string));
dt.Columns.Add("TargetEncoding", typeof(string));
dt.Columns.Add("Result", typeof(string));
dt.Columns.Add("SourceEncodingName", typeof(string));
dt.Columns.Add("TargetEncodingName", typeof(string));

// For reference
// https://msdn.microsoft.com/en-us/library/system.text.encodinginfo.getencoding(v=vs.110).aspx
int[] encs = new int[] {
20127 // US-ASCII
,28591 // iso-8859-1 Western European (ISO)
,28592 // iso-8859-2 Central European (ISO)
,28593 // iso-8859-3 Latin 3 (ISO)
,28594 // iso-8859-4 Baltic (ISO)
,28595 // iso-8859-5 Cyrillic (ISO)
,28596 // iso-8859-6 Arabic (ISO)
,28597 // iso-8859-7 Greek (ISO)
,28598 // iso-8859-8 Hebrew (ISO-Visual)
,28599 // iso-8859-9 Turkish (ISO)
,28603 // iso-8859-13 Estonian (ISO)
,28605 // iso-8859-15 Latin 9 (ISO)

,1250 // windows-1250 Central European (Windows)
,1251 // windows-1251 Cyrillic (Windows)
,1252 // Windows-1252 Western European (Windows)
,1253 // windows-1253 Greek (Windows)
,1254 // windows-1254 Turkish (Windows)
,1255 // windows-1255 Hebrew (Windows)
,1256 // windows-1256 Arabic (Windows)
,1257 // windows-1257 Baltic (Windows)
,1258 // windows-1258 Vietnamese (Windows)

,20866 // Cyrillic (KOI8-R)
,21866 // Cyrillic (KOI8-U)

,65000 // UTF-7
,65001 // UTF-8
,1200 // UTF-16
,1201 // Unicode (Big-Endian)

,12000 // UTF-32
,12001 // UTF-32BE (UTF-32 Big-Endian)
};


for (int i = 0; i < encs.Length; ++i)
{

for (int j = 0; j < encs.Length; ++j)
{
System.Data.DataRow dr = dt.NewRow();

dr["SourceEncoding"] = encs[i];
dr["TargetEncoding"] = encs[j];


System.Text.Encoding enci = Encoding.GetEncoding(encs[i]);
System.Text.Encoding encj = Encoding.GetEncoding(encs[j]);

byte[] encoded = enci.GetBytes(broken);
string corrected = encj.GetString(encoded);

dr["Result"] = corrected;

dr["SourceEncodingName"] = enci.BodyName;
dr["TargetEncodingName"] = encj.BodyName;


if (StringComparer.InvariantCultureIgnoreCase.Equals(correct, corrected))
dt.Rows.Add(dr);
}

}

this.dataGridView1.DataSource = dt;
}
}

或者更彻底,只测试所有编码:

private void btnTestAll_Click(object sender, EventArgs e)
{
dt = new System.Data.DataTable();

string correct = "Brokers México, Intermediario de Aseguro,S.A.";

string broken = "Brokers México, Intermediario de Aseguro,S.A."; // Get text from database

dt.Columns.Add("SourceEncoding", typeof(string));
dt.Columns.Add("TargetEncoding", typeof(string));
dt.Columns.Add("Result", typeof(string));
dt.Columns.Add("SourceEncodingName", typeof(string));
dt.Columns.Add("TargetEncodingName", typeof(string));



System.Text.EncodingInfo[] encs = System.Text.Encoding.GetEncodings();

for (int i = 0; i < encs.Length; ++i)
{

for (int j = 0; j < encs.Length; ++j)
{
System.Data.DataRow dr = dt.NewRow();

dr["SourceEncoding"] = encs[i].CodePage;
dr["TargetEncoding"] = encs[j].CodePage;


System.Text.Encoding enci = System.Text.Encoding.GetEncoding(encs[i].CodePage);
System.Text.Encoding encj = System.Text.Encoding.GetEncoding(encs[j].CodePage);

byte[] encoded = enci.GetBytes(broken);
string corrected = encj.GetString(encoded);

dr["Result"] = corrected;

dr["SourceEncodingName"] = enci.BodyName;
dr["TargetEncodingName"] = encj.BodyName;


if (StringComparer.InvariantCultureIgnoreCase.Equals(correct, corrected))
dt.Rows.Add(dr);
}

}

this.dataGridView1.DataSource = dt;
}

您可以下载结果here :

很奇怪,看起来你可以从 German/ANSI(或 ISO-8859-1)转换为 ASCII,但是没有办法将它转换回来(信息丢失)...

public static string lol()
{
string source = "Alu-Dreieckstütze";

// System.Text.Encoding encSource = System.Text.Encoding.Default;
System.Text.Encoding encSource = System.Text.Encoding.GetEncoding(28591);
System.Text.Encoding encTarget = System.Text.Encoding.ASCII;

byte[] encoded = encSource.GetBytes(source);
string broken = encTarget.GetString(encoded);

return broken;
}

有趣的是,由于旧版应用程序正确显示它,所以它不可能丢失信息。

那么你确定你没有在 Sqlite connectionString 中输入错误的(或没有)编码吗?

例如

  "Data Source=C:\\Users\\USERNAME\\Desktop\\location.db; Version=3; UseUTF16Encoding=True;Synchronous=Normal;New=False"; // set up the connection string

https://www.sqlite.org/c3ref/c_any.html

看起来您可以使用 pragma encoding 测试编码

关于c# - 如何将数据库中存储在 ANSI (Windows 1252) 中的值转换为 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33033514/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com