10

PHP コード:

echo hash('sha256', 'jake');

PHP 出力:

cdf30c6b345276278bedc7bcedd9d5582f5b8e0c1dd858f46ef4ea231f92731d

Java コード:

String s = "jake";
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(s.getBytes(Charset.forName("UTF-8")));
byte[] hashed = md.digest();
String s2 = "";
for (byte b : hashed) {
    s2 += b;
}
System.out.println(s2);

Java 出力:

-51-1312107528211839-117-19-57-68-19-39-43884791-1141229-4088-12110-12-223531-11011529

この 2 つが同じ結果を返すことを期待していました。明らかに、そうではありません。2つを一致させるにはどうすればよいですか、それとも不可能ですか?

編集:私は間違いを犯しました。とにかく、質問に対する答えがあると思います。

4

3 に答える 3

13

さて、あなたがする必要がある最初のことは、一貫した文字列エンコーディングを使用することです。PHPが何をするかはわかりません"jake".getBytes()が、Java用のプラットフォームのデフォルトエンコーディングを使用します。それは本当に悪い考えです。PHPが最初にUnicode文字列を処理することを前提とすると、UTF-8を使用することはおそらく良いスタートです。(そうでない場合は、それ何をしているのかを理解し、2つを一貫させるようにする必要があります。)Javaでは、String.getBytes()aをとるオーバーロードCharsetまたは。の名前をとるオーバーロードを使用しCharsetます。(個人的にはGuavaを使用するのが好きCharsets.UTF_8です。)

次に、PHPにUTF-8も使用するように説得します。

次に、Javaの結果を16進数で出力します。あなたが与えたコードがあなたが実行している実際のコードであるかどうかは非常に疑わしいです。そうでなければ、「[B@e48e1b」のような出力を期待します。バイト配列を文字列に変換するために何をしていても、16進数を使用するように変更します。

于 2011-01-13T13:44:17.003 に答える
6

彼らは同じものを印刷しています..バイト[]を16進文字列に変換すると、CDF30C6B345276278BEDC7BCEDD9D5582F5B8E0C1DD858F46EF4EA231F92731DもJava出力として表示されます。

public void testSomething() throws Exception {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update("jake".getBytes());
    System.out.println(getHex(md.digest()));
}

static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
    if ( raw == null ) {
      return null;
    }
    final StringBuilder hex = new StringBuilder( 2 * raw.length );
    for ( final byte b : raw ) {
      hex.append(HEXES.charAt((b & 0xF0) >> 4))
         .append(HEXES.charAt((b & 0x0F)));
    }
    return hex.toString();
}
于 2011-01-13T13:50:19.513 に答える
2

印刷する前に、ダイジェストをHEX文字列に変換する必要があります。サンプルコードはここにあります。

于 2011-01-13T13:44:31.653 に答える