整数型の配列のハッシュコード
byte型配列にファイルを読み込んでGetHashCodeメソッドでハッシュコードを取れば、CRC32を自前で実装したりSHA1とかの結果を圧縮したりしなくても32bitのハッシュ値を返すハッシュ関数として使えるのではないか?
と思ったので配列のハッシュコードについて調べてみた。
整数型の配列のハッシュコード
単にbyte型だとそのまま32bit整数型にキャストされたものが返ってくるが、byte型配列の場合は同じ配列でもインスタンスが異なればハッシュコードも異なるようだ。
これもSSCLIのソースコードを追いかけてみたが、配列の基本クラスであるSystem.Arrayクラスには定義されていなかった。ということは派生元のObject.GetHashCode()が呼ばれていることになるが、こいつはさらにInternalGetHashCode(this)という関数の結果を返している。さらにさらにInternalGetHashCode(this)はObjectNative::GetHashCode(Object)を呼び出し、さらにさらにさらにObjectNative::GetHashCodeEx(Object)を呼び出している。
この中で使われている関数が何をしているのかとすべてのコードパスを調べるのはさすがに面倒くさい。見た感じ、インスタンス生成時にObjectに与えられるヘッダ(?)を元に、一意になるようにハッシュコードを計算しているっぽい。(まあ、CLRがSSCLIと同じように実装しているとは限らないが……)
まとめ
配列のハッシュコードは内容によらず一意なものを返す。よってbyte型配列にファイルの内容を読み込んでもGetHashCodeメソッドをハッシュ関数としては使えない。