-
Notifications
You must be signed in to change notification settings - Fork 127
/
hash.go
62 lines (52 loc) · 1.1 KB
/
hash.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
package crypto
import (
"bytes"
"encoding/hex"
"fmt"
"strconv"
"golang.org/x/crypto/sha3"
)
type Hash [32]byte
func NewHash(data []byte) Hash {
return Hash(sha3.Sum256(data))
}
func HashFromString(src string) (Hash, error) {
var hash Hash
data, err := hex.DecodeString(src)
if err != nil {
return hash, err
}
if len(data) != len(hash) {
return hash, fmt.Errorf("invalid hash length %d", len(data))
}
copy(hash[:], data)
return hash, nil
}
func (h Hash) HasValue() bool {
zero := Hash{}
return bytes.Compare(h[:], zero[:]) != 0
}
func (h Hash) ForNetwork(net Hash) Hash {
return NewHash(append(net[:], h[:]...))
}
func (h Hash) String() string {
return hex.EncodeToString(h[:])
}
func (h Hash) MarshalJSON() ([]byte, error) {
return []byte(strconv.Quote(h.String())), nil
}
func (h *Hash) UnmarshalJSON(b []byte) error {
unquoted, err := strconv.Unquote(string(b))
if err != nil {
return err
}
data, err := hex.DecodeString(string(unquoted))
if err != nil {
return err
}
if len(data) != len(h) {
return fmt.Errorf("invalid hash length %d", len(data))
}
copy(h[:], data)
return nil
}