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