【问题标题】:How to generate Java's String hashCode using Ruby如何使用 Ruby 生成 Java 的 String hashCode
【发布时间】:2014-03-30 04:28:41
【问题描述】:

我想在 Ruby 中生成 Java 的 String.hashCode 方法返回的相同哈希码。什么方法最优雅? Java 的 String hashCode 实现在这里描述:http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode%28%29

【问题讨论】:

  • 您是否已经实现了自己的任何实现?了解您的想法以提出更好的方法是值得的:)
  • 不方便的部分是模拟 Java 的 int 算法,因为 Ruby 将 Fixnum 提升为 Bignum。
  • 我的实现是否有任何更新或任何缺失?
  • 我正在寻找完全模仿 Java 行为的方法。谢谢!

标签: java ruby string hashcode


【解决方案1】:

这是我的版本。它的作用与 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 实现返回一个 32 位宽的 int(无符号为 31 位)。 Java 哈希码实现也可能返回负值。此实现不会模仿 java 的负面哈希码行为。相反,它将返回一个介于 0 和 2**31-1(Integer.MAX_VALUE) 之间的整数

    【讨论】:

      【解决方案3】:

      这是一个与java中的hashCode()返回相同结果的例子

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-26
        • 2011-12-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        相关资源
        最近更新 更多