PHP代码:

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

PHP输出:

CDF30C6B345276278BEDC7BCEDD9D55582F5B8E0C1D858F458F46EF4EA231F92731D

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

我原本希望这两个返回相同的结果。显然,事实并非如此。我该如何使两者匹配或不可能?

编辑:我犯了一个错误,认为我现在对问题有答案。

有帮助吗?

解决方案

好吧, 最先 您需要做的是使用一致的字符串编码。我不知道PHP会做什么,但是 "jake".getBytes() 将使用您的平台默认编码用于Java的任何内容。那是一个 真的很糟糕. 。假设PHP与Unicode字符串开始,则使用UTF-8可能是一个好的开始。 (如果没有,您需要确定它 做并尝试使两者保持一致。)在Java中,使用超负荷 String.getBytes() 这是一个 Charset 或以 Charset. 。 (我个人喜欢使用番石榴 Charsets.UTF_8.)

然后说服PHP也使用UTF-8。

然后输出Java导致十六进制。我非常怀疑您给出的代码是您正在运行的实际代码,否则我希望输出,例如“ [B@e48e1b”。无论您正在做什么将字节数组转换为字符串,都可以将其更改为使用十六进制。

其他提示

他们正在打印相同的。将您的字节[]转换为十六进制字符串,然后您将看到CDF3345276278BEDC7BCEDD9D9D55582F5B8E0C1DD858F46EF46EF46EA231F92731D

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();
}

在打印出来之前,您需要将摘要转换为十六进制字符串。可以找到示例代码 这里.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top