hex.go
3.4 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2016 Tom Thorogood. All rights reserved.
// Use of this source code is governed by a
// Modified BSD License license that can be found in
// the LICENSE file.
//
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hex is an efficient hexadecimal implementation for Golang.
package hex
import (
"errors"
"fmt"
)
var errLength = errors.New("go-hex: odd length hex string")
var (
lower = []byte("0123456789abcdef")
upper = []byte("0123456789ABCDEF")
)
// InvalidByteError values describe errors resulting from an invalid byte in a hex string.
type InvalidByteError byte
func (e InvalidByteError) Error() string {
return fmt.Sprintf("go-hex: invalid byte: %#U", rune(e))
}
// EncodedLen returns the length of an encoding of n source bytes.
func EncodedLen(n int) int {
return n * 2
}
// DecodedLen returns the length of a decoding of n source bytes.
func DecodedLen(n int) int {
return n / 2
}
// Encode encodes src into EncodedLen(len(src))
// bytes of dst. As a convenience, it returns the number
// of bytes written to dst, but this value is always EncodedLen(len(src)).
// Encode implements lowercase hexadecimal encoding.
func Encode(dst, src []byte) int {
return RawEncode(dst, src, lower)
}
// EncodeUpper encodes src into EncodedLen(len(src))
// bytes of dst. As a convenience, it returns the number
// of bytes written to dst, but this value is always EncodedLen(len(src)).
// EncodeUpper implements uppercase hexadecimal encoding.
func EncodeUpper(dst, src []byte) int {
return RawEncode(dst, src, upper)
}
// EncodeToString returns the lowercase hexadecimal encoding of src.
func EncodeToString(src []byte) string {
return RawEncodeToString(src, lower)
}
// EncodeUpperToString returns the uppercase hexadecimal encoding of src.
func EncodeUpperToString(src []byte) string {
return RawEncodeToString(src, upper)
}
// RawEncodeToString returns the hexadecimal encoding of src for a given
// alphabet.
func RawEncodeToString(src, alpha []byte) string {
dst := make([]byte, EncodedLen(len(src)))
RawEncode(dst, src, alpha)
return string(dst)
}
// DecodeString returns the bytes represented by the hexadecimal string s.
func DecodeString(s string) ([]byte, error) {
src := []byte(s)
dst := make([]byte, DecodedLen(len(src)))
if _, err := Decode(dst, src); err != nil {
return nil, err
}
return dst, nil
}
// MustDecodeString is like DecodeString but panics if the string cannot be
// parsed. It simplifies safe initialization of global variables holding
// binary data.
func MustDecodeString(str string) []byte {
dst, err := DecodeString(str)
if err != nil {
panic(err)
}
return dst
}
func encodeGeneric(dst, src, alpha []byte) {
for i, v := range src {
dst[i*2] = alpha[v>>4]
dst[i*2+1] = alpha[v&0x0f]
}
}
func decodeGeneric(dst, src []byte) (uint64, bool) {
for i := 0; i < len(src)/2; i++ {
a, ok := fromHexChar(src[i*2])
if !ok {
return uint64(i * 2), false
}
b, ok := fromHexChar(src[i*2+1])
if !ok {
return uint64(i*2 + 1), false
}
dst[i] = (a << 4) | b
}
return 0, true
}
// fromHexChar converts a hex character into its value and a success flag.
func fromHexChar(c byte) (byte, bool) {
switch {
case '0' <= c && c <= '9':
return c - '0', true
case 'a' <= c && c <= 'f':
return c - 'a' + 10, true
case 'A' <= c && c <= 'F':
return c - 'A' + 10, true
}
return 0, false
}