-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathhasher.go
76 lines (65 loc) · 1.43 KB
/
hasher.go
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
package bloomfilter
import (
"crypto/md5" // skipcq: GSC-G501
"crypto/sha1" // skipcq: GSC-G505
"encoding/binary"
"fmt"
"hash"
"hash/crc64"
"hash/fnv"
)
type Hash func([]byte) []uint
type HashFactory func(uint) []Hash
const (
HASHER_DEFAULT = "default"
HASHER_OPTIMAL = "optimal"
)
var (
defaultHashers = []Hash{
MD5,
CRC64,
SHA1,
FNV64,
FNV128,
}
HashFactoryNames = map[string]HashFactory{
HASHER_DEFAULT: DefaultHashFactory,
HASHER_OPTIMAL: OptimalHashFactory,
}
ErrImpossibleToTreat = fmt.Errorf("unable to union")
MD5 = HashWrapper(md5.New()) // skipcq: GO-S1023, GSC-G401
SHA1 = HashWrapper(sha1.New()) // skipcq: GO-S1025, GSC-G401
CRC64 = HashWrapper(crc64.New(crc64.MakeTable(crc64.ECMA)))
FNV64 = HashWrapper(fnv.New64())
FNV128 = HashWrapper(fnv.New128())
)
func DefaultHashFactory(k uint) []Hash {
if k > uint(len(defaultHashers)) {
k = uint(len(defaultHashers))
}
return defaultHashers[:k]
}
func OptimalHashFactory(k uint) []Hash {
return []Hash{
func(b []byte) []uint {
hs := FNV128(b)
out := make([]uint, k)
for i := range out {
out[i] = hs[0] + uint(i)*hs[1]
}
return out
},
}
}
func HashWrapper(h hash.Hash) Hash {
return func(elem []byte) []uint {
h.Reset()
h.Write(elem)
result := h.Sum(nil)
out := make([]uint, len(result)/8)
for i := 0; i < len(result)/8; i++ {
out[i] = uint(binary.LittleEndian.Uint64(result[i*8 : (i+1)*8]))
}
return out
}
}