0
嘿,朋友,我试图在ruby中实现一个Java“哈希”函数。把一个字符串的MD5散列的最重要的8个字节作为一个长(在红宝石)
这里的Java方面:
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;
}
到目前为止,红宝石我最好的猜测是:
# 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
问题是,这个Ruby代码不匹配的java输出。
作为参考,给出这些字符串上面的Java代码返回相应的长:
"00038c53790ecedfeb2f83102e9115a522475d73" => -2059313900129568948
"0" => -3473083983811222033
"001211e8befc8ac22dd265ecaa77f8c227d0007f" => 3234260774580957018
思想:
- 我有从红宝石串获得UTF8字节问题
- 在红宝石我使用
hexdigest
,我怀疑我应该只使用digest
而不是 - Java代码是采取md 5的UTF8字节,而我的红宝石代码是采取md5的字节(如十六进制)
任何建议如何获得完全相同的输出在红宝石?
不,测试用例是正确的。 Java long类型是64位_signed_整数类型,因此具有最高有效位集的值将产生负数。如上所述,0xcfcd208495d565ef的值为14973660089898329583 - 2^64 = -3473083983811222033。 – 2010-04-29 19:47:27
@Thomas Pornin:是的,你是对的。我想我只是不习惯破碎算术的语言。 – 2010-04-29 21:43:28