3

http://www.developerfusion.com/tools/convert/csharp-to-vb/を使用してVBに変換したこのC#コードがあります

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

スクランブルは特定の方法で配列を再配置するだけで、VB出力とC#出力を相互にチェックしたので、無視できます。入力と出力はバイト配列であるため、エンコーディングに影響を与えることはありません。

問題は、この関数の結果がハッシュアルゴリズムに入力され、ハッシュ署名と比較されることにあります。VBバージョンの結果は、ハッシュされた場合、署名と一致しません。

コメントから、バイトバッファを文字列として取得するためにさまざまなエンコーディングを使用しようとしましたが、いずれも機能しなかったことがわかります。

問題はtoの翻訳にあるdecoded += Convert.ToString((char)buffer[i]);ようdecoded += Convert.ToString(ChrW(buffer(index)))です。

ChrWはcharとしてキャストするのと同じ結果を生成し、どのエンコーディングがバイト配列の読み取りを正しく複製しますか?

編集:私は常にOption Strict Onを使用していますが、元のC#がオンになっていない可能性があるため、暗黙的な変換の影響を受ける可能性があります。その状況でコンパイラは何をしますか?

4

4 に答える 4

3

素早い回答

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

と同等です

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

VB.Netは、c#コードで使用されているハッキーなアプローチをとることを阻止します。aCharはUnicodeであるため、2バイトで構成されます。


これはあなたが持っているもののより良い実装のように見えます。

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
于 2012-10-03T09:30:17.153 に答える
0

以下を試してみてください。

decoded += Convert.ToChar(foo)

これは機能しますが(暗黙の変換がフレームワーク固有であり、言語固有ではないと仮定した前回の試みとは異なります)、.NETと同じになることを保証することはできません。

あなたが使用することを期待したコメントであなたが言うとしたらEncoding.xxx.GetString、なぜあなたはそれを使用しませんか?元の文字列からバイト配列のエンコーディングを知っていますか?もしそうなら、それを使用してください。とにかくバイト配列を文字列に変換する正しい方法です。バイトごとに変換すると、マルチバイト文字では間違いなく壊れてしまうからです(明らかに)。

于 2012-10-02T16:09:19.387 に答える
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が有効な仮定ではない可能性があるユニコードコードポイントであると仮定します(0から127まではこれは問題ではないと思いますが、バイトの上半分は異なる可能性があります)。これが問題である場合は、アクセントが付けられている可能性があり、問題を引き起こしている他のそのような「特殊」文字があります。

于 2012-10-02T16:10:55.850 に答える
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
于 2014-02-06T00:06:17.043 に答える