9

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.

1
  • 2
    Check your character encoding - PHP works with bytes, does Java use UTF8 or UTF16 (or what)? Commented Jan 13, 2011 at 13:44

3 Answers 3

13

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Python tends to use ISO-8859-1, but is trying to adopt Unicode, so this may depend on the version. For 'jake', an all-ASCII string, this should yield the same as UTF-8. Nevertheless, I warmly second the consistent string encoding requirement.
@Thomas: Yup - I felt it was important to get that right first, before the rest... because otherwise, as soon as the OP saw a "working" digest (e.g. just by converting his existing byte array to hex) they might well decide to declare victory :)
6

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

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.