I want to generate, in Ruby, the same hash code returned by Java's String.hashCode method. What approach would be most elegant? Java's String hashCode implementation is described here: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode%28%29
Asked
Active
Viewed 1,516 times
1
-
Have you arrived at any implementation of your own? It would be worth knowing your ideas to suggest the better way :) – Kashyap Mar 30 '14 at 04:33
-
The inconvenient part is simulating the int arithmetic of Java since Ruby promotes Fixnum to Bignum. – fooledbyprimes Mar 30 '14 at 05:14
-
Any updates or anything my implementation is missing ? – bsd Apr 02 '14 at 13:14
-
I'm looking for full mimic of Java behavior. Thanks! – fooledbyprimes Apr 17 '14 at 18:43
3 Answers
5
This is my version. It does the same as javascript hashCode. Note the 32 bit conversion trick packing and unpacking:
def hash_code(str)
str.each_char.reduce(0) do |result, char|
[((result << 5) - result) + char.ord].pack('L').unpack('l').first
end
end

Ungue
- 442
- 5
- 14
3
Here is a simple implementation.
def jhash(str)
result = 0
mul = 1
max_mod = 2**31 - 1
str.chars.reverse_each do |c|
result += mul * c.ord
result %= max_mod
mul *= 31
end
result
end
And some sample runs
jhash("aa")
3104
jhash("")
0
jhash("polygenelubricants") #Java returns -2147483648
1283535072
Note that the java implementation returns a int which is 32 bits wide(31 bits for unsigned). The Java hashcode implementation may also return negative values. This implementation will not mimic java's negative hashcode behaviour. Instead it will return a whole number between 0 and 2**31-1(Integer.MAX_VALUE)

bsd
- 2,707
- 1
- 17
- 24
-2
This is an example that returns the same result as hashCode() in java
TWO_31 = 2 ** 31
TWO_32 = 2 ** 32
def java_hash_code(str)
size = str.size
hash = 0
str.chars.each_with_index do |ch, i|
hash += ch.ord * (31 ** (size-(i+1)))
hash = hash % TWO_32 - TWO_31
end
hash
end

dongqs
- 1