Java SHA256 输出与 PHP SHA256 不同的哈希值?

发布于 2024-10-12 06:49:09 字数 637 浏览 3 评论 0原文

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

我原以为两者会返回相同的结果。显然,事实并非如此。我怎样才能让两者匹配或者这是不可能的?

编辑:我犯了一个错误,我想我现在已经有了问题的答案。

PHP code:

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

PHP output:

cdf30c6b345276278bedc7bcedd9d5582f5b8e0c1dd858f46ef4ea231f92731d

Java code:

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 output:

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

I had expected the two to return the same result. Obviously, this is not the case. How can I get the two to match up or is it impossible?

EDIT: I had made a mistake, think I have the answer to the question now anyway.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

彻夜缠绵 2024-10-19 06:49:09

嗯,您需要做的第一件事就是使用一致的字符串编码。我不知道 PHP 会做什么,但是 "jake".getBytes() 将使用您的平台默认的 Java 编码。这是一个非常糟糕的主意。假设 PHP 一开始就处理 Unicode 字符串,那么使用 UTF-8 可能是一个好的开始。 (如果没有,您需要弄清楚它正在做什么,并尝试使两者保持一致。)在 Java 中,使用 String.getBytes()< 的重载/code> 接受一个 Charset 或接受一个 Charset 的名称。 (我个人喜欢使用 Guava 的 Charsets.UTF_8。)

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

然后以十六进制输出 Java 结果。我非常怀疑您给出的代码是您正在运行的实际代码,否则我希望得到诸如“[B@e48e1b”之类的输出。无论您如何将字节数组转换为字符串,请将其更改为使用十六进制。

Well, the very first thing you need to do is use a consistent string encoding. I've no idea what PHP will do, but "jake".getBytes() will use whatever your platform default encoding is for Java. That's a really bad idea. Using UTF-8 would probably be a good start, assuming that PHP copes with Unicode strings to start with. (If it doesn't, you'll need to work out what it is doing and try to make the two consistent.) In Java, use the overload of String.getBytes() which takes a Charset or the one which takes the name of a Charset. (Personally I like to use Guava's Charsets.UTF_8.)

Then persuade PHP to use UTF-8 as well.

Then output the Java result in hex. I very much doubt that the code you've given is the actual code you're running, as otherwise I'd expect output such as "[B@e48e1b". Whatever you're doing to convert the byte array into a string, change it to use hex.

苍风燃霜 2024-10-19 06:49:09

他们正在打印相同的..将您的 byte[] 转换为十六进制字符串,然后您也会看到 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();
}

They are printing the same .. convert your byte[] to a hex string, then you'll see CDF30C6B345276278BEDC7BCEDD9D5582F5B8E0C1DD858F46EF4EA231F92731D as Java output, too:

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();
}
草莓味的萝莉 2024-10-19 06:49:09

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

You need to convert the digest to a HEX string before printing it out. Example code can be found here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文