我正在尝试编写一个将接受所有数据类型的哈希。 一旦进入函数,我将数据作为字节数组处理。 我在弄清楚如何将任意
我尝试使用二进制包,但它似乎取决于传入的数据类型。
所有数据类型的大小都是字节的某个倍数(甚至是布尔值),因此理论上这应该很简单。
下面有问题的代码,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 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 } |
- pkg"编码/目标"怎么样? 可以使用吗?
- @nvcnvn,似乎正在工作。 我早些时候尝试过,但现在我意识到小值(0-62是否相同?)的哈希值存在缺陷。 我更改了我现在使用的范围,现在似乎可以使用。 谢谢!
- 修复了哈希fn中的错误,可在此处找到更新的代码:gist.github.com/natebrennand/10442587
我代码中的其他问题使我较早离开了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 } |
- 随意接受自己的答案作为问题的答案:)
- 举个例子说明这个方法的用法会很高兴。 对于像Go这样的许多初学者来说,这确实有助于分配!
将
1 2 3 4 5 | /* * Convert variable `key` from interface{} to []byte */ byteKey := []byte(fmt.Sprintf("%v", key.(interface{}))) |
fmt.Sprintf将接口值转换为字符串。
[] byte将字符串值转换为字节。
※注意※如果interface {}值为指针,则此方法不起作用。 请在下面找到@PassKit的评论。
- 如果该接口是一个指针,您将获得一个内存地址,则可能会产生意想不到的结果。 play.golang.org/p/EgjvrqOyxEi
- 在您的答案中值得一提的是@PassKit在他的评论中所说的