使用正确的编码将字节数组转换为字符串

时间:2012-10-02 16:04:13

标签: c# vb.net migration

我有一些C#代码,我已使用http://www.developerfusion.com/tools/convert/csharp-to-vb/

将其转换为VB
private string DecodeToken (string token, string key)
{           
    byte [] buffer = new byte[0];
    string decoded = "";
    int i;
        if (Scramble (Convert.FromBase64String(token), key, ref buffer))
    {
        for (i=0;i<buffer.Length;i++)
        {
            decoded += Convert.ToString((char)buffer[i]);
        }
    }
    return(decoded);
}

经过一点修改后,给出了这个:

Private Function DecodeToken(token As String, key As String) As String
    Dim buffer As Byte()
    Dim decoded As String = ""
    Dim index As Integer
    If Scramble(Convert.FromBase64String(token), key, buffer) Then
        For index = 0 To buffer.Length - 1
            decoded += Convert.ToString(ChrW(buffer(index)))
        Next
        'decoded = UTF8Encoding.ASCII.GetString(pbyBuffer)
        'decoded = UnicodeEncoding.ASCII.GetString(pbyBuffer)
        'decoded = ASCIIEncoding.ASCII.GetString(pbyBuffer)
    End If
    Return decoded
End Function

Scramble只是以特定的方式重新排列数组,我已经检查了VB和C#输出,因此可以忽略它。它的输入和输出是字节数组,所以它不应该影响编码。

问题在于将此函数的结果输入散列算法,然后将其与散列签名进行比较。当哈希值时,VB版本的结果与签名不匹配。

您可以从评论中看到我尝试使用不同的编码将字节缓冲区作为字符串输出,但这些都没有用。

问题似乎在于decoded += Convert.ToString((char)buffer[i]);decoded += Convert.ToString(ChrW(buffer(index)))的转换。

ChrW是否产生与作为char进行转换相同的结果以及哪种编码将正确复制字节数组的读取?

编辑:我总是有Option Strict On但原始C#可能没有,所以它可能会受到隐式转换的影响。编译器在那种情况下做了什么?

4 个答案:

答案 0 :(得分:3)

快速回答

decoded += Convert.ToString((char)buffer[i]);

相当于

decoded &= Convert.ToString(Chr(buffer[i]));

VB.Net阻止你采用c#代码中使用的hacky方法,Char是Unicode,因此包含两个字节。


这看起来更像是你所拥有的更好的实现。

Private Function DecodeToken(encodedToken As String, key As String) As String
    Dim scrambled = Convert.FromBase64String(encodedToken)
    Dim buffer As Byte()
    Dim index As Integer

    If Not Scramble(scrambled, key, buffer) Then
        Return Nothing
    End If

    Dim descrambled = new StringBuilder(buffer.Length);

    For index = 0 To buffer.Length - 1
        descrambled.Append(Chr(buffer(index)))
    Next

    Return descrambled.ToString()
End Function

答案 1 :(得分:0)

给出以下内容:

decoded += Convert.ToChar(foo)

它可以工作(不像我上次尝试假设隐式转换是特定于框架而不是特定于语言)但我不能保证它与.NET相同。

鉴于您在评论中说您希望使用Encoding.xxx.GetString,那么为什么不使用它?你知道原始字符串到字节数组的编码是什么吗?如果是这样,那就用吧。无论如何,将字节数组转换为字符串是正确的方法,因为对于任何多字节字符(明显地),逐字节执行它肯定会中断。​​

答案 2 :(得分:0)

您是否尝试过最直接的代码翻译:

decoded += Convert.ToString(CType(buffer[i], char))

当将字节数组连接到字符串时,您应该确保首先知道编码。如果在提供字节数组的任何设置中设置了这个,那么你应该用它来解码字符串。

有关ChrW(和Chr)函数的更多详细信息,请查看http://msdn.microsoft.com/en-us/library/613dxh46%28v=vs.80%29.aspx。本质上,ChrW假设传递的int是一个unicode代码点,这可能不是一个有效的假设(我相信从0到127这无关紧要,但字节的上半部分可能不同)。如果这是问题,那么它可能会被重音和其他导致问题的“特殊”字符。

答案 3 :(得分:0)

小改进

Private Function DecodeToken(encodedToken As String, key As String) As String
    Dim scrambled = Convert.FromBase64String(encodedToken)
    Dim buffer As Byte()
    Dim index As Integer

    If Not Scramble(scrambled, key, buffer) Then
        Return Nothing
    End If

    Dim descrambled = System.Text.Encoding.Unicode.GetString(buffer, 0, buffer.Length);

    Return descrambled
End Function