为什么Encoding.Default.GetBytes()在VB.NET和C#中返回不同的结果?

问题描述:

我们最近遇到了一些供应商的示例代码,用于散列Web服务调用的密钥,他们的示例是在我们转换为C#的VB.NET中。这导致哈希产生不同的输入。事实证明,他们为加密生成密钥的方式是将char数组转换为字符串并返回到字节数组。这让我发现VB.NET和C#的默认编码器与某些字符的工作方式不同。为什么Encoding.Default.GetBytes()在VB.NET和C#中返回不同的结果?

C#:

Console.Write(Encoding.Default.GetBytes(new char[] { (char)149 })[0]); 

VB:

Dim b As Char() = {Chr(149)} 
Console.WriteLine(Encoding.Default.GetBytes(b)(0)) 

C#的输出为63,而VB是149 如果你使用任何其他值,如145等正确的字节值,输出匹配。

通过调试,VB和C#默认编码器都是SBCSCodePageEncoding。

有谁知道这是为什么?

我已经通过直接初始化一个字节数组来纠正示例代码,它应该放在第一位,但我仍然想知道为什么编码器不应该是语言特定的,看起来就是这样。

如果你使用ChrW(149),你会得到一个不同的结果63,和C#一样。

Dim b As Char() = {ChrW(149)} 
Console.WriteLine(Encoding.Default.GetBytes(b)(0)) 

the documentation看到,将解释答案

+2

下面是对文件的链接:http://msdn.microsoft .com/en-us/library/613dxh46(VS.80).aspx – 2009-05-29 19:25:47

default encoding是机器相关的,也取决于线程,因为它使用当前的代码页。你通常应该使用像Encoding.UTF8这样的东西,这样你就不必担心当一台机器使用unicode而另一台机器使用1252-ANSI时会发生什么。

不同的操作系统可能会使用 不同的编码作为默认值。 因此,从一个 操作系统到另一个操作系统的数据流可能被 翻译不正确。为确保 的编码字节正确解码为 ,您的应用程序应使用一个Unicode编码,即 UTF8Encoding,UnicodeEncoding或 UTF32Encoding,并带有前导码。 另一种选择是使用更高级别的协议来确保 使用相同的格式来编码 并进行解码。

http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx

你可以查阅一下每种语言产生,当你明确地编码使用UTF8?

的VB Chr函数需要一个参数,在0至255的范围内difference-,并将其转换为使用当前的默认代码页的字符。如果你在这个范围之外传递一个参数,它会抛出异常。

ChrW将采取一个16位值并返回相应的系统。不使用编码的字符值 - 因此会得到与您发布的C#代码相同的结果。

在C#中的VB代码的大致相当于不使用VB字符串类(这是一个包含*委员会和CHRW类)是:

char[] chars = Encoding.Default.GetChars(new byte[] { 149 }); 
Console.Write(Encoding.Default.GetBytes(chars)[0]); 

相信在VB相当于是CHRW(149) 。

所以,这个VB代码...

Dim c As Char() = New Char() { Chr(149) } 
    'Dim c As Char() = New Char() { ChrW(149) } 
    Dim b As Byte() = System.Text.Encoding.Default.GetBytes(c) 
    Console.WriteLine("{0}", Convert.ToInt32(c(0))) 
    Console.WriteLine("{0}", CInt(b(0))) 

产生输出作为此C#代码一样...

var c = new char[] { (char)149 }; 
    var b = System.Text.Encoding.Default.GetBytes(c); 
    Console.WriteLine("{0}", (int)c[0]); 
    Console.WriteLine("{0}", (int) b[0]);