-
Notifications
You must be signed in to change notification settings - Fork 0
/
hash.go
107 lines (88 loc) · 1.78 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
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
package types
import (
"encoding/hex"
"fmt"
"math/big"
"github.com/koinotice/vite/crypto"
)
const (
HashSize = 32
)
type Hash [HashSize]byte
var ZERO_HASH = Hash{}
func BytesToHash(b []byte) (Hash, error) {
var h Hash
err := h.SetBytes(b)
return h, err
}
func HexToHash(hexstr string) (Hash, error) {
if len(hexstr) != 2*HashSize {
return Hash{}, fmt.Errorf("error hex hash size %v", len(hexstr))
}
b, err := hex.DecodeString(hexstr)
if err != nil {
return Hash{}, err
}
return BytesToHash(b)
}
func HexToHashPanic(hexstr string) Hash {
h, err := HexToHash(hexstr)
if err != nil {
panic(err)
}
return h
}
func (h *Hash) SetBytes(b []byte) error {
if len(b) != HashSize {
return fmt.Errorf("error hash size %v", len(b))
}
copy(h[:], b)
return nil
}
func (h Hash) Hex() string {
return hex.EncodeToString(h[:])
}
func (h Hash) Bytes() []byte {
return h[:]
}
func (h Hash) String() string {
return h.Hex()
}
func (h Hash) Big() *big.Int {
return new(big.Int).SetBytes(h[:])
}
func (h Hash) IsZero() bool {
return h == ZERO_HASH
}
func BigToHash(b *big.Int) (Hash, error) {
slice := b.Bytes()
if len(slice) < HashSize {
padded := make([]byte, HashSize)
copy(padded[HashSize-len(slice):], slice)
return BytesToHash(padded)
} else {
return BytesToHash(slice)
}
}
func DataHash(data []byte) Hash {
h, _ := BytesToHash(crypto.Hash256(data))
return h
}
func DataListHash(data ...[]byte) Hash {
h, _ := BytesToHash(crypto.Hash256(data...))
return h
}
func (h *Hash) UnmarshalJSON(input []byte) error {
if !isString(input) {
return ErrJsonNotString
}
hash, e := HexToHash(string(trimLeftRightQuotation(input)))
if e != nil {
return e
}
h.SetBytes(hash.Bytes())
return nil
}
func (h Hash) MarshalText() ([]byte, error) {
return []byte(h.String()), nil
}