字节转字符串再转字节的转换出现错误令人困惑

4

请问有谁可以帮忙找出错误?这是代码:

   byte[] oriBytes = { 0xB0, 0x2D };                       // oriBytes -> 0xB0, 0x2D
   string oriInStr = Encoding.ASCII.GetString(oriBytes);   // oriInStr ->   "?-"
   oriBytes = Encoding.ASCII.GetBytes(oriInStr);           // oriBytes -> 0x3F, 0x2D

我无法还原0xB0, 0x2D的原始字节值。


1
你为什么要使用ASCII解码?你的输入限制在ASCII范围内吗? - Piyush Parashar
使用 Encoding.Default,它实现了您操作系统中使用的代码页。 - leppie
我刚刚解决了它。只需使用Encoding.Unicode而不是ASCII。我处理电子硬件,ARM和PIC的每个字节位。 - sam byte
请确保在解码时了解输入编码,否则您将遇到类似的错误。 - Piyush Parashar
5个回答

8

0xB0不是有效的ASCII码。您可以在这里阅读:

大于十六进制0x7F的任何字节都将解码为Unicode问号(“?”)


4
因为显然.NET 不支持 扩展ASCII表。127以上的每个值都会产生?,即63
因此,将?转换回来将导致63
在使用UTF8编码运行代码时,您将看到它进入了扩展页面,因为此示例中的newBytes返回4个字节而不是2个:
byte[] oriBytes = { 0xB0, 0x2D };
string oriInStr = Encoding.UTF8.GetString(oriBytes);
byte[] newBytes = Encoding.UTF8.GetBytes(oriInStr);

1
在你的byte[]中,0xB0会变成176,0x2D会变成45。当转换为只有128个字符的ASCII码时,176会给你一个未定义的结果,而45会给你一个减号“-”。
尝试调试代码并查看发生了什么。

0

正如其他人所提到的,.Net不支持扩展ASCII码。为了解决这个问题,您应该将字节值转换为char类型,它本质上是int类型,并且会正确地映射它们。

 byte[] oriBytes = { 0xB0, 0x2D };                      
 string oriInStr = "";
 for (int a = 0; a < oriBytes.Length; a++)
     oriInStr += (char)(oriBytes[a]);
 oriBytes = Encoding.ASCII.GetBytes(oriInStr); 

你测试过你的代码了吗?它会产生完全相同的结果!0x3F,0x2D - sam byte
我做了,你打印出来了吗? - Vajura

0

哈哈.. 我懂了!使用 Encoding.Unicode 而不是 ASCII。小心啊... ;)

   byte[] oriBytes = { 0xB0, 0x2D };                         // oriBytes -> 0xB0, 0x2D
   string oriInStr = Encoding.Unicode.GetString(oriBytes);   // oriInStr ->   "?-"
   oriBytes = Encoding.Unicode.GetBytes(oriInStr);           // oriBytes -> 0xB0, 0x2D

如果您实际上不想要该字符串以 ASCII 表示,那么这个确实有效。 - Vajura
我用一个非常长的字符串(文本)进行了测试,实际上复制了半页。将其转换为字节数组,然后再转回字符串。我可以得到原始文本...只是要注意这个简单的错误。它可能会导致严重的头痛,至少对我来说是这样... ;) - sam byte

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