Take most significant 8 bytes of the MD5 hash of a string as a long (in Ruby)

Posted by Nate Murray on Stack Overflow See other posts from Stack Overflow or by Nate Murray
Published on 2010-04-29T14:45:22Z Indexed on 2010/04/29 14:47 UTC
Read the original article Hit count: 409

Filed under:
|
|
|
|

Hey Friends, I'm trying to implement a java "hash" function in ruby.

Here's the java side:

import java.nio.charset.Charset;
import java.security.MessageDigest;

/**
 * @return most significant 8 bytes of the MD5 hash of the string, as a long
 */
protected long hash(String value) {
  byte[] md5hash;
  md5hash = md5Digest.digest(value.getBytes(Charset.forName("UTF8")));
  long hash = 0L;
  for (int i = 0; i < 8; i++) {
    hash = hash << 8 | md5hash[i] & 0x00000000000000FFL;
  }
  return hash;
}

So far, my best guess in ruby is:

# WRONG - doesn't work properly.
#!/usr/bin/env ruby -wKU

require 'digest/md5'
require 'pp'

md5hash = Digest::MD5.hexdigest("0").unpack("U*")
pp md5hash
hash = 0
0.upto(7) do |i|
  hash = hash << 8 | md5hash[i] & 0x00000000000000FF
end
pp hash

Problem is, this ruby code doesn't match the java output.

For reference, the above java code given these strings returns the corresponding long:

"00038c53790ecedfeb2f83102e9115a522475d73" => -2059313900129568948
"0" => -3473083983811222033
"001211e8befc8ac22dd265ecaa77f8c227d0007f" => 3234260774580957018

Thoughts:

  • I'm having problems getting the UTF8 bytes from the ruby string
  • In ruby I'm using hexdigest, I suspect I should be using just digest instead
  • The java code is taking the md5 of the UTF8 bytes whereas my ruby code is taking the bytes of the md5 (as hex)

Any suggestions on how to get the exact same output in ruby?

© Stack Overflow or respective owner

Related posts about ruby

Related posts about java