forked from skull-squadron/bloomfilter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinaryunmarshaler.go
111 lines (90 loc) · 2.28 KB
/
binaryunmarshaler.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Package bloomfilter is face-meltingly fast, thread-safe,
// marshalable, unionable, probability- and
// optimal-size-calculating Bloom filter in go
//
// https://github.com/steakknife/bloomfilter
//
// Copyright © 2014, 2015, 2018 Barry Allard
//
// MIT license
//
package bloomfilter
import (
"bytes"
"crypto/hmac"
"crypto/sha512"
"encoding/binary"
"io"
)
func unmarshalBinaryHeader(r io.Reader) (k, n, m uint64, err error) {
err = binary.Read(r, binary.LittleEndian, &k)
if err != nil {
return k, n, m, err
}
if k < KMin {
return k, n, m, errK()
}
err = binary.Read(r, binary.LittleEndian, &n)
if err != nil {
return k, n, m, err
}
err = binary.Read(r, binary.LittleEndian, &m)
if err != nil {
return k, n, m, err
}
if m < MMin {
return k, n, m, errM()
}
debug("read bf k=%d n=%d m=%d\n", k, n, m)
return k, n, m, err
}
func unmarshalBinaryBits(r io.Reader, m uint64) (bits []uint64, err error) {
bits, err = newBits(m)
if err != nil {
return bits, err
}
err = binary.Read(r, binary.LittleEndian, bits)
return bits, err
}
func unmarshalBinaryKeys(r io.Reader, k uint64) (keys []uint64, err error) {
keys = make([]uint64, k)
err = binary.Read(r, binary.LittleEndian, keys)
return keys, err
}
func checkBinaryHash(r io.Reader, data []byte) (err error) {
expectedHash := make([]byte, sha512.Size384)
err = binary.Read(r, binary.LittleEndian, expectedHash)
if err != nil {
return err
}
actualHash := sha512.Sum384(data[:len(data)-sha512.Size384])
if !hmac.Equal(expectedHash, actualHash[:]) {
debug("bloomfilter.UnmarshalBinary() sha384 hash failed:"+
" actual %v expected %v", actualHash, expectedHash)
return errHash()
}
debug("bloomfilter.UnmarshalBinary() successfully read"+
" %d byte(s), sha384 %v", len(data), actualHash)
return nil
}
// UnmarshalBinary converts []bytes into a Filter
// conforms to encoding.BinaryUnmarshaler
func (f *Filter) UnmarshalBinary(data []byte) (err error) {
f.lock.Lock()
defer f.lock.Unlock()
buf := bytes.NewBuffer(data)
var k uint64
k, f.n, f.m, err = unmarshalBinaryHeader(buf)
if err != nil {
return err
}
f.keys, err = unmarshalBinaryKeys(buf, k)
if err != nil {
return err
}
f.bits, err = unmarshalBinaryBits(buf, f.m)
if err != nil {
return err
}
return checkBinaryHash(buf, data)
}