Take most significant 8 bytes of the MD5 hash of a string as a long (in Ruby)
- by Nate Murray
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?