我正在尝试编写一个将接受所有数据类型的哈希。一旦进入函数,我将数据作为字节数组处理。我在弄清楚如何将任意类型interface{}转换为字节数组时遇到麻烦。
interface{}
我尝试使用二进制包,但它似乎取决于传入的数据类型Write()。fn (docs)的参数之一需要知道参数的字节顺序。
Write()
所有数据类型的大小都是字节的某个倍数(甚至是布尔值),因此理论上这应该很简单。
下面有问题的代码,
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, b, c = mix(a, b, 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, b, c = mix(a, b, c) return c, nil } func mix(a, b, 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, b, c }
代码中的其他问题使我gob较早离开了软件包,事实证明这是@nvcnvn建议的正确方法。以下有关如何解决此问题的相关代码:
gob
package bloom import ( "encoding/gob" "bytes" ) func GetBytes(key interface{}) ([]byte, error) { var buf bytes.Buffer enc := gob.NewEncoder(&buf) err := enc.Encode(key) if err != nil { return nil, err } return buf.Bytes(), nil }