-
Notifications
You must be signed in to change notification settings - Fork 699
/
hex.go
121 lines (99 loc) · 2.78 KB
/
hex.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
112
113
114
115
116
117
118
119
120
121
package hex
import (
"encoding/hex"
"fmt"
"math/big"
"strconv"
"strings"
)
const (
// Base represents the hexadecimal base, which is 16
Base = 16
// BitSize64 64 bits
BitSize64 = 64
)
// DecError represents an error when decoding a hex value
type DecError struct{ msg string }
func (err DecError) Error() string { return err.msg }
// EncodeToHex generates a hex string based on the byte representation, with the '0x' prefix
func EncodeToHex(str []byte) string {
return "0x" + hex.EncodeToString(str)
}
// EncodeToString is a wrapper method for hex.EncodeToString
func EncodeToString(str []byte) string {
return hex.EncodeToString(str)
}
// DecodeString returns the byte representation of the hexadecimal string
func DecodeString(str string) ([]byte, error) {
return hex.DecodeString(str)
}
// DecodeHex converts a hex string to a byte array
func DecodeHex(str string) ([]byte, error) {
str = strings.TrimPrefix(str, "0x")
// Check if the string has an odd length
if len(str)%2 != 0 {
// Prepend a '0' to make it even-length
str = "0" + str
}
return hex.DecodeString(str)
}
// MustDecodeHex type-checks and converts a hex string to a byte array
func MustDecodeHex(str string) []byte {
buf, err := DecodeHex(str)
if err != nil {
panic(fmt.Errorf("could not decode hex: %v", err))
}
return buf
}
// DecodeUint64 type-checks and converts a hex string to a uint64
func DecodeUint64(str string) uint64 {
i := DecodeBig(str)
return i.Uint64()
}
// EncodeUint64 encodes a number as a hex string with 0x prefix.
func EncodeUint64(i uint64) string {
enc := make([]byte, 2, 10) //nolint:gomnd
copy(enc, "0x")
return string(strconv.AppendUint(enc, i, Base))
}
// BadNibble is a nibble that is bad
const BadNibble = ^uint64(0)
// DecodeNibble decodes a byte into a uint64
func DecodeNibble(in byte) uint64 {
switch {
case in >= '0' && in <= '9':
return uint64(in - '0')
case in >= 'A' && in <= 'F':
return uint64(in - 'A' + 10) //nolint:gomnd
case in >= 'a' && in <= 'f':
return uint64(in - 'a' + 10) //nolint:gomnd
default:
return BadNibble
}
}
// EncodeBig encodes bigint as a hex string with 0x prefix.
// The sign of the integer is ignored.
func EncodeBig(bigint *big.Int) string {
numBits := bigint.BitLen()
if numBits == 0 {
return "0x0"
}
return fmt.Sprintf("%#x", bigint)
}
// DecodeBig converts a hex number to a big.Int value
func DecodeBig(hexNum string) *big.Int {
str := strings.TrimPrefix(hexNum, "0x")
createdNum := new(big.Int)
createdNum.SetString(str, Base)
return createdNum
}
// IsValid checks if the provided string is a valid hexadecimal value
func IsValid(s string) bool {
str := strings.TrimPrefix(s, "0x")
for _, b := range []byte(str) {
if !(b >= '0' && b <= '9' || b >= 'a' && b <= 'f' || b >= 'A' && b <= 'F') {
return false
}
}
return true
}