我试图写一个将接受所有数据类型的哈希值。一旦处于函数中,我将数据作为字节数组处理。我无法弄清楚如何将任意界面{}投射到一个字节数组中。
我尝试使用二进制包,但它似乎取决于传入的数据类型。Write()fn (docs)的一个参数需要知道参数的字节顺序。
所有的数据类型大小都是一个字节的几何(甚至是bool),所以这在理论上应该是简单的。
下面的代码,
package bloom import ( "encoding/gob" "bytes" ) // adapted from http://bretmulvey.com/hash/7.html func ComputeHash(key interface{}) (uint,error) { var buf bytes.Buffer enc := gob.NewEncoder(&buf) err := enc.Encode(key) if err != nil { return 0,err } data := buf.Bytes() var a,b,c uint a,b = 0x9e3779b9,0x9e3779b9 c = 0; i := 0; for i = 0; i < len(data)-12; { a += uint(data[i+1] | data[i+2] << 8 | data[i+3] << 16 | data[i+4] << 24) i += 4 b += uint(data[i+1] | data[i+2] << 8 | data[i+3] << 16 | data[i+4] << 24) i += 4 c += uint(data[i+1] | data[i+2] << 8 | data[i+3] << 16 | data[i+4] << 24) a,c = mix(a,c); } c += uint(len(data)) if i < len(data) { a += uint(data[i]) i++ } if i < len(data) { a += uint(data[i] << 8) i++ } if i < len(data) { a += uint(data[i] << 16) i++ } if i < len(data) { a += uint(data[i] << 24) i++ } if i < len(data) { b += uint(data[i]) i++ } if i < len(data) { b += uint(data[i] << 8) i++ } if i < len(data) { b += uint(data[i] << 16) i++ } if i < len(data) { b += uint(data[i] << 24) i++ } if i < len(data) { c += uint(data[i] << 8) i++ } if i < len(data) { c += uint(data[i] << 16) i++ } if i < len(data) { c += uint(data[i] << 24) i++ } a,c) return c,nil } func mix(a,c uint) (uint,uint,uint){ a -= b; a -= c; a ^= (c>>13); b -= c; b -= a; b ^= (a<<8); c -= a; c -= b; c ^= (b>>13); a -= b; a -= c; a ^= (c>>12); b -= c; b -= a; b ^= (a<<16); c -= a; c -= b; c ^= (b>>5); a -= b; a -= c; a ^= (c>>3); b -= c; b -= a; b ^= (a<<10); c -= a; c -= b; c ^= (b>>15); return a,c }