49911
RubyのHash値取得に関する質問です．  
下記のコードにおいて，実行毎に変化しないハッシュ値を取得したいのですが，どのように対処すればよいのでしょうか．  
ご教授お願い致します．

```

    # ハッシュ値を取得してある値を計算するテストコード
    require 'test/unit'
    require 'cmath'
    
    # 引数のハッシュ値に基づく乱数生成器を設定する
    def uniqueRandom(*args)
      sumHash = 0
      args.each{ |i|
        p i.to_s + "のHash値" + i.hash.to_s
        sumHash = sumHash + i.hash
      }
      rnd = Random.new(sumHash)
      return rnd
    end
    
    class UnitTest < Test::Unit::TestCase
      def test_getHashValue
        rnd = uniqueRandom(10, "Channel")
        p (1.0 / 17.4905) * CMath.exp(Complex(Math.cos(rnd.rand(1.0)), Math.sin(rnd.rand(1.0))) * 2 * Math::PI)
      end
    end
    
```
CC BY-SA 4.0
2018-11-02T10:34:53.080
49902
2018-11-02T22:44:35.063
30173
question
ruby-on-rails ruby
固定したハッシュ値を取得したい
[Zlib.#crc32](https://docs.ruby-
lang.org/ja/latest/method/Zlib/m/crc32.html)が使うと文字列のみ依存で一定となるCRC-32の整数値(Integer)を返します。

```

    require 'zlib'
    str = 'hoge'
    crc = Zlib.crc32(str)
    p crc #=> 2335827034 (環境異存なし)
    
```

CRC-32の範囲は符号無し32bit整数値です。そのためRandomのシード値として使用した場合、たかだが232しかパターンがありません。より多くのパターンを生成した場合はdigestモジュールを使用します。

```

    str = 'hoge'
    
    require 'digest/md5'
    md5 = Digest::MD5.hexdigest(str).to_i(16) # 128bits
    p md5 #=> 311622155487174517432991262857998412670
    
    require 'digest/rmd160'
    rmd160 = Digest::RMD160.hexdigest(str).to_i(16) # 160bits
    p rmd160 #=> 421215687515797509955010976893163978158450862449
    
    require 'digest/sha1'
    sha1 = Digest::SHA1.hexdigest(str).to_i(16) # 160bits
    p sha1 #=> 285160836105145057295564030126526459180476620348
    
    require 'digest/sha2'
    sha256 = Digest::SHA256.hexdigest(str).to_i(16) # 256bits
    sha384 = Digest::SHA384.hexdigest(str).to_i(16) # 384bits
    sha512 = Digest::SHA512.hexdigest(str).to_i(16) # 512bits
    p sha256 #=> 1070681082186409...5136609985194021
    p sha384 #=> 3142410166718590...8678657356121888
    p sha512 #=> 1150699269346398...6863431099807449
    
```

いずれの値も環境に依存せずに文字列によって常に同じになります。

なお、CRC-32は値から元の文字列を推測できる場合がありますので、セッション値生成などセキュリティーに関わる部分には使用しないでください。ダイジェスト関数であってもMD5やSHA1は脆弱性が発見されていますので、ビット数に応じた強度を持つとは考えないでください。(そもそも、セキュリティに関わる部分にRandomは使用すべきではなく、SecureRandomを使用すべきですが)
CC BY-SA 4.0
2018-11-02T22:44:35.063
49911
2018-11-02T22:44:35.063
7347
49902
answer