Java SHA256は、異なるハッシュをPHP SHA256に出力しますか?
質問
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つを一致させることができますか、それとも不可能ですか?
編集:私は間違いを犯しました、とにかく今質問に対する答えがあると思います。
解決
さて、 最初に 必要なことは、一貫した文字列エンコードを使用することです。 PHPが何をするかはわかりませんが "jake".getBytes()
プラットフォームのデフォルトエンコードがJava用に使用するものは何でも使用します。それはです 本当に悪い考え. 。 PHPが最初からUnicode文字列に対処すると仮定して、UTF-8を使用することはおそらく良いスタートです。 (そうでない場合、あなたはそれが何をする必要がありますか は 2つを一貫して行うようにしてください。)Javaで、の過負荷を使用します String.getBytes()
かかります Charset
またはaの名前を取るもの Charset
. 。 (個人的にはグアバを使うのが好きです Charsets.UTF_8
.)
次に、PHPを説得して、UTF-8も使用します。
その後、Javaの結果はヘックスになります。そうでなければ「[B@e48e1b」などの出力が期待されるため、あなたが与えたコードが実際のコードであることを非常に疑っています。バイト配列を文字列に変換するために何をしているにしても、160個を使用するように変更します。
他のヒント
彼らは同じものを印刷しています。バイト[]を16進ストリングに変換してから、CDF30C6B345276278BEDC7BCEDD9D5582F5B8E0C1DD858F46EA231F92731Dが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();
}
印刷する前に、ダイジェストを16進ストリングに変換する必要があります。サンプルコードを見つけることができます ここ.