ASCIIEncoding.ASCII.GetBytes()返回意外值

本文关键字:返回 意外 ASCII GetBytes ASCIIEncoding | 更新日期: 2023-09-27 18:08:59

这段c#代码…

string s = "'u00C0";
byte[] bytes = ASCIIEncoding.ASCII.GetBytes(s);
Trace.WriteLine(BitConverter.ToString(bytes));

产生以下输出:

3F

为什么输出不是C0?

ASCIIEncoding.ASCII.GetBytes()返回意外值

因为'u00c0不是ASCII(0-127范围)。因此,它被编码为问号- ? (0x3F)。

参见MSDN关于ASCIIEncoding的文章:

ASCIIEncoding对应于Windows代码页20127。因为ASCII是7位编码,所以ASCII字符被限制为最低的128个Unicode字符,从U+0000到U+007F。方法返回的默认编码器。ASCII属性或ASCIIEncoding构造函数,在执行编码操作之前,超出该范围的字符将被替换为问号(?)。

您似乎想要一个表示Unicode字符字符串的字节序列。显然,字节数将取决于编码。由于您期望C0是其中一个字节,因此它缩小了选项范围。这是UTF16LE,当然是两个字节,因为'u00c0完全代表一个BMP字符:

string s = "'u00C0";
byte[] bytes = Encoding.Unicode.GetBytes(s);
Trace.WriteLine(BitConverter.ToString(bytes));

你应该阅读《每个软件开发人员绝对必须知道的关于Unicode和字符集的绝对最低限度》(没有借口!)

第一步:将unicode char传递给string,然后将其转换为ASCII(但它是unicode)。然后您正在尝试使用unicode转换器将其转换回来。

下面的例子尽一切可能使我的回答更清楚:

    static void Main(string[] args)
    {
        string s = "'u00C0";
        Console.WriteLine(s);
        byte[] bytes = ASCIIEncoding.ASCII.GetBytes(s);
        Console.WriteLine(BitConverter.ToString(bytes));
        Console.WriteLine(ASCIIEncoding.ASCII.GetString(bytes));
        Console.WriteLine("Again");
        bytes = Encoding.UTF8.GetBytes(s);
        Console.WriteLine(BitConverter.ToString(bytes));
        Console.WriteLine(Encoding.UTF8.GetString(bytes));
        Console.ReadLine();
    }

输出为:

A
3F
?
Again
C3-80
A

BitConverter的定义。GetBytes是:

转换指定数组中每个元素的数值字节转换为等价的十六进制字符串表示形式。