2

私はこのコードを変換します:

strtoupper(bin2hex(mhash(mhash_sha512, "$ico{$product[0]}{$user[1]}")));

C# に:

byte[] data = SHA512.Create().ComputeHash(Encoding.ASCII.GetBytes(args[0]));
string result = "";
for(int index = 0; index < data.Length; index++)
    result += data[index].ToString("X2");

そしてそれは非常にうまく機能します。しかし、入力を UTF16 に変換しようとすると、次のようになります。

strtoupper(bin2hex(mhash(mhash_sha512, iconv('UTF-8', 'UTF-16', "$ico{$product[0]}{$user[1]}"))));

C# では、Encoding クラスを使用して変換します。

SHA512.Create().ComputeHash(Encoding.Convert(Encoding.ASCII/UTF8, Encoding.GetEncoding("UTF-16"), Encoding.ASCII/UTF8.GetBytes(args[0])));

それは機能しません。両方の言語から同じ出力を取得する必要があります。C#言語で文字列(「bbb」)をUTF16に正しく変換するにはどうすればよいですか? ありがとうございました...

4

1 に答える 1

4

リトル エンディアン UTF-16 エンコーディングの場合は、ビッグ エンディアン UTF-16 の場合は「Encoding.BigEndianUnicode」に変更しますEncoding.GetEncoding("UTF-16")Encoding.Unicode

さらに調べてみると (たとえば、UTF-8 は Encoding.ASCII と同じではありません)、これは PHP コードの適切な翻訳でしょうか?

var bytesToHash = Encoding.Convert(Encoding.UTF8, Encoding.BigEndianUnicode, Encoding.UTF8.GetBytes(args[0]));
var result = string.Concat(SHA512.Create().ComputeHash(bytesToHash).Select(b => b.ToString("X2")));

私はこの php mhash 関数の期待される出力に精通していませんが、おそらくこれを試すことができます:

var hash = new System.Security.Cryptography.SHA512CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(data));
var hashString = BitConverter.ToString(hash);
var phpLikeHash = hashString.Replace("-", String.Empty).ToUpper();

更新 OK、あなたの新しい情報に基づいて、私が含めた最初の例は、入力のエンコード変換が必要ない場合に機能します。したがって、これは少なくとも、PHP の mhash と同じ出力を生成する SHA512 に依存できること、および相違点が入力として提供されるバイトに関連していることを確認します。

PHP コードと C# の両方で、入力として同じリテラル文字列を使用して、さまざまなエンコーディングを少し試してみることをお勧めします。以下の例のように:

    static bool HashIt(Encoding source, Encoding dest, string input, string expectedOutput)
    {
        byte[] bytes = source.GetBytes(input);
        if (source != dest && dest != null)
            bytes =  Encoding.Convert(source, dest, bytes);
        var hash = SHA512.Create().ComputeHash(bytes);
        var hashString = string.Concat(hash.Select(b => b.ToString("X2")));
        if (hashString.Equals(expectedOutput))
        {
            Console.WriteLine("Match found");
            Console.WriteLine("Source encoding: {0}", source.WebName);
            if (source != dest && dest != null)
                Console.WriteLine("Converted to: {0}", dest.WebName);
            return true;
        }
        return false;
    }

    static void Main(string[] args)
    {
        var inputs = new [] { "13338170AS875HEO49F8Sam-PC", @"13338170AS875HEO49F8Sam-PC" };
        var expectedOutput = "A91A64DD4DF1880651CB6B919BE02C4363ED6D4B07EA246CF47FFB509918E4AA4C294FF8BA9F73E5‌​CD1CE463BB3E66F84A6C294D70C781CD0610345BCADEEDA7";
        var encodings = Encoding.GetEncodings().Select(e => e.GetEncoding());
        var matchFound = false;
        foreach (var srcEncoding in encodings)
        {
            foreach (var input in inputs)
            {
                if (HashIt(srcEncoding, null, input, expectedOutput))
                    matchFound = true;
                foreach (var destEncoding in encodings)
                {
                    if (HashIt(srcEncoding, destEncoding, input, expectedOutput))
                        matchFound = true;
                }
            }
        }
        if (!matchFound)
            Console.WriteLine("No matches found");
        Console.ReadLine();
    }

私のシステムで次の出力が生成されます。

No matches found

だからあなたは運が悪いかもしれません。現時点では、他に何を試すべきかわかりません。

于 2013-08-16T20:37:47.387 に答える