为什么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看到,将解释答案
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]);
下面是对文件的链接:http://msdn.microsoft .com/en-us/library/613dxh46(VS.80).aspx – 2009-05-29 19:25:47