代码之家  ›  专栏  ›  技术社区  ›  Annagram

为什么encoding.default.getbytes()在vb.net和c中返回不同的结果?

  •  7
  • Annagram  · 技术社区  · 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。

    有人知道这是为什么吗?

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

    5 回复  |  直到 17 年前
        1
  •  10
  •   RichardOD    17 年前

    如果使用chrw(149),您将得到不同的结果-63,与c_相同。

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

    the documentation 看看有什么不同-这就解释了答案

        2
  •  5
  •   to StackOverflow    17 年前

    vb chr函数接受范围为0到255的参数,并使用当前默认代码页将其转换为字符。如果传递的参数超出此范围,则会引发异常。

    chrw将获取一个16位的值,并返回相应的system.char值,而不使用编码,因此将得到与您发布的c代码相同的结果。

    如果不使用vb strings类(即包含chr和chrw的类),C中的vb代码的近似等效值为:

    char[] chars = Encoding.Default.GetChars(new byte[] { 149 });
    Console.Write(Encoding.Default.GetBytes(chars)[0]);
    
        3
  •  0
  •   JasonRShaver    17 年前

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

        4
  •  0
  •   gehsekky    17 年前

    不同的操作系统可能会使用 默认为不同的编码。 因此,数据从一个 另一个操作系统可能是 翻译错误。确保 编码的字节被解码 正确地说,您的应用程序应该使用 一种Unicode编码,即, utf8编码、单编码编码或 utf32编码,带前导码。 另一种选择是使用 更高级别的协议以确保 相同的格式用于编码 并进行解码。

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

    当您使用UTF8显式编码时,您能检查每种语言产生什么吗?

        5
  •  0
  •   Cheeso    17 年前

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