Как сгенерировать хеш-код Java String с использованием Ruby

1

Я хочу сгенерировать в Ruby тот же хэш-код, возвращаемый методом Java String.hashCode. Какой подход был бы самым элегантным? Реализация хеш-кода Java String описана здесь: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode%28%29

  • 0
    Вы достигли какой-либо собственной реализации? Стоит знать ваши идеи, чтобы предложить лучший способ :)
  • 0
    Неудобная часть моделирует внутреннюю арифметику Java, поскольку Ruby продвигает Fixnum в Bignum.
Показать ещё 2 комментария
Теги:
string
hashcode

3 ответа

2

Это моя версия. Он делает то же самое, что и javascript hashCode. Обратите внимание, что упаковка и распаковка 32-битного конвертирования:

  def hash_code(str)
    str.each_char.reduce(0) do |result, char|
      [((result << 5) - result) + char.ord].pack('L').unpack('l').first
    end
  end
2

Вот простая реализация.

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

И некоторые образцы пробега

jhash("aa")
3104

jhash("")
0 

jhash("polygenelubricants") #Java returns -2147483648
1283535072

Обратите внимание, что реализация java возвращает int, который имеет ширину 32 бит (31 бит для unsigned). Реализация Java hashcode также может возвращать отрицательные значения. Эта реализация не будет имитировать поведение отрицательного хэш-кода java. Вместо этого он будет возвращать целое число от 0 до 2 ** 31-1 (Integer.MAX_VALUE)

-3

Это пример, который возвращает тот же результат, что и hashCode() в 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню