【问题标题】:Why Encoding.Default.GetBytes() returns different results in VB.NET and C#?为什么 Encoding.Default.GetBytes() 在 VB.NET 和 C# 中返回不同的结果?
【发布时间】:2009-05-29 19:12:17
【问题描述】:

我们最近遇到了一些来自供应商的示例代码,用于对 Web 服务调用的密钥进行哈希处理,他们的示例在 VB.NET 中,我们将其转换为 C#。这导致散列产生不同的输入。事实证明,他们生成加密密钥的方式是将 char 数组转换为字符串,然后再转换回字节数组。这让我发现 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。

有人知道这是为什么吗?

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

【问题讨论】:

    标签: c# vb.net encoding


    【解决方案1】:

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

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

    阅读the documentation 了解不同之处——这将解释答案

    【讨论】:

    • 干杯 Jon- 我刚刚在添加链接。
    • 谢谢!我认为它与 Chr() 位有关,但我不确定如何避免在 VB.NET 中使用 Chr()。
    • 我认为您得到不同结果的原因尚不清楚。基于the other answer,你的答案会根据Windows的默认编码而改变。
    【解决方案2】:

    VB Chr 函数采用 0 到 255 范围内的参数,并使用当前默认代码页将其转换为字符。如果您传递超出此范围的参数,它将引发异常。

    ChrW 将采用 16 位值并在不使用编码的情况下返回相应的 System.Char 值 - 因此将给出与您发布的 C# 代码相同的结果。

    在不使用 VB 字符串类(即包含 Chr 和 ChrW 的类)的情况下,C# 中的 VB 代码的近似等效项是:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        不同的操作系统可能使用 不同的编码作为默认值。 因此,数据流从一个 操作系统到另一个可能是 翻译错误。为了保证 编码的字节被解码 正确地,您的应用程序应该使用 Unicode 编码,即 UTF8Encoding、UnicodeEncoding 或 UTF32Encoding,带序言。 另一种选择是使用 更高级别的协议,以确保 相同的格式用于编码 和解码。

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

        当您使用 utf8 显式编码时,您能否检查每种语言产生的内容?

        【讨论】:

          【解决方案5】:

          我相信 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]);
          

          【讨论】:

            猜你喜欢
            • 2010-10-31
            • 2013-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-28
            • 2013-03-10
            • 1970-01-01
            相关资源
            最近更新 更多