我有一些十六进制数据:
48|65|6c|6c|6f|20|53|68|61|72|6f|6b|2e|
20|3d|43|46|3d|46|30|3d|45|38|3d|45|32|3d|45|35|3d|46|32|0d|0a|0d|0a|2e|0d|0a|
第一个文本字符串是“Hello Sharok”(没有引号)。第二个文本字符串是“Привет”(没有引号,“Привет”在俄语中是“Hello”)。如何将其转换为可读文本(第一个字符串正常,第二个字符串失败。)?
代码页:Windows-1251(CP1251)
答案 0 :(得分:3)
第二个字符串不是Windows-1251,而是quoted-printable“=CF=F0=E8=E2=E5=F2<CR><LF><CR><LF>.
”,其中的解码字符实际上是Windows-1251。因此,您需要迭代字符串,并逐个构建输出字符串。如果遇到转义符号(=),则接下来的两个字符是Windows-1251的十六进制数字。解码两位数并将结果字符添加到输出字符串。循环直到结束。
答案 1 :(得分:2)
对于第二个,你可以使用它:
string input="20|3d|43|46|3d|46|30|3d|45|38|3d|45|32|3d|45|35|3d|46|32|0d|0a|0d|0a|2e|0d|0a";
byte[] bytes=input.Split('|').Select(s=>byte.Parse(s, System.Globalization.NumberStyles.HexNumber)).ToArray();
string text = Encoding.GetEncoding(1251).GetString(bytes);
StringBuilder text2=new StringBuilder();
for(int i=0;i<text.Length;i++)
{
if (text[i]=='=')
{
string hex=text[i+1].ToString()+text[i+2].ToString();
byte b=byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
text2.Append(Encoding.GetEncoding(1251).GetString(new byte[]{b}));
i+=2;
}
else
{
text2.Append(text[i]);
}
}
首先解码|分开的字符串。其中包含=转义的十六进制值,以下循环解码。
答案 2 :(得分:1)
看看这里
How can I convert a cp1251 byte array to a utf8 String?
这很有用
http://bytes.com/topic/c-sharp/answers/274352-utf8-windows-1251-conversion
答案 3 :(得分:1)
为windows-1251编码创建一个Encoding
对象,并解码字节数组:
byte[] data = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x53, 0x68, 0x61, 0x72, 0x6f, 0x6b, 0x2e
};
string text = Encoding.GetEncoding(1251).GetString(data);
第二组数据不会解码为俄语字符,而是解析为这个(包括开头的空格和换行符(CR + LF)结束三行中的每一行):
=CF=F0=E8=E2=E5=F2
.
要获取所需的字符串,首先必须将数据解码为字符串,然后从字符串中提取十六进制代码,将这些代码转换为字节,然后解码这些字节:
Encoding win = Encoding.GetEncoding(1251);
string text = win.GetString(
Regex.Matches(win.GetString(data), "=(..)")
.OfType<Match>()
.Select(m => Convert.ToByte(m.Groups[1].Value, 16))
.ToArray()
);