1
2
3
4
5
6 package hex
7
8 import (
9 "errors"
10 "fmt"
11 "io"
12 "strings"
13 )
14
15 const hextable = "0123456789abcdef"
16
17
18
19 func EncodedLen(n int) int { return n * 2 }
20
21
22
23
24
25 func Encode(dst, src []byte) int {
26 j := 0
27 for _, v := range src {
28 dst[j] = hextable[v>>4]
29 dst[j+1] = hextable[v&0x0f]
30 j += 2
31 }
32 return len(src) * 2
33 }
34
35
36
37
38 var ErrLength = errors.New("encoding/hex: odd length hex string")
39
40
41 type InvalidByteError byte
42
43 func (e InvalidByteError) Error() string {
44 return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e))
45 }
46
47
48
49 func DecodedLen(x int) int { return x / 2 }
50
51
52
53
54
55
56
57
58 func Decode(dst, src []byte) (int, error) {
59 i, j := 0, 1
60 for ; j < len(src); j += 2 {
61 a, ok := fromHexChar(src[j-1])
62 if !ok {
63 return i, InvalidByteError(src[j-1])
64 }
65 b, ok := fromHexChar(src[j])
66 if !ok {
67 return i, InvalidByteError(src[j])
68 }
69 dst[i] = (a << 4) | b
70 i++
71 }
72 if len(src)%2 == 1 {
73
74
75 if _, ok := fromHexChar(src[j-1]); !ok {
76 return i, InvalidByteError(src[j-1])
77 }
78 return i, ErrLength
79 }
80 return i, nil
81 }
82
83
84 func fromHexChar(c byte) (byte, bool) {
85 switch {
86 case '0' <= c && c <= '9':
87 return c - '0', true
88 case 'a' <= c && c <= 'f':
89 return c - 'a' + 10, true
90 case 'A' <= c && c <= 'F':
91 return c - 'A' + 10, true
92 }
93
94 return 0, false
95 }
96
97
98 func EncodeToString(src []byte) string {
99 dst := make([]byte, EncodedLen(len(src)))
100 Encode(dst, src)
101 return string(dst)
102 }
103
104
105
106
107
108
109
110 func DecodeString(s string) ([]byte, error) {
111 src := []byte(s)
112
113
114 n, err := Decode(src, src)
115 return src[:n], err
116 }
117
118
119
120 func Dump(data []byte) string {
121 if len(data) == 0 {
122 return ""
123 }
124
125 var buf strings.Builder
126
127
128
129 buf.Grow((1 + ((len(data) - 1) / 16)) * 79)
130
131 dumper := Dumper(&buf)
132 dumper.Write(data)
133 dumper.Close()
134 return buf.String()
135 }
136
137
138 const bufferSize = 1024
139
140 type encoder struct {
141 w io.Writer
142 err error
143 out [bufferSize]byte
144 }
145
146
147 func NewEncoder(w io.Writer) io.Writer {
148 return &encoder{w: w}
149 }
150
151 func (e *encoder) Write(p []byte) (n int, err error) {
152 for len(p) > 0 && e.err == nil {
153 chunkSize := bufferSize / 2
154 if len(p) < chunkSize {
155 chunkSize = len(p)
156 }
157
158 var written int
159 encoded := Encode(e.out[:], p[:chunkSize])
160 written, e.err = e.w.Write(e.out[:encoded])
161 n += written / 2
162 p = p[chunkSize:]
163 }
164 return n, e.err
165 }
166
167 type decoder struct {
168 r io.Reader
169 err error
170 in []byte
171 arr [bufferSize]byte
172 }
173
174
175
176 func NewDecoder(r io.Reader) io.Reader {
177 return &decoder{r: r}
178 }
179
180 func (d *decoder) Read(p []byte) (n int, err error) {
181
182 if len(d.in) < 2 && d.err == nil {
183 var numCopy, numRead int
184 numCopy = copy(d.arr[:], d.in)
185 numRead, d.err = d.r.Read(d.arr[numCopy:])
186 d.in = d.arr[:numCopy+numRead]
187 if d.err == io.EOF && len(d.in)%2 != 0 {
188 if _, ok := fromHexChar(d.in[len(d.in)-1]); !ok {
189 d.err = InvalidByteError(d.in[len(d.in)-1])
190 } else {
191 d.err = io.ErrUnexpectedEOF
192 }
193 }
194 }
195
196
197 if numAvail := len(d.in) / 2; len(p) > numAvail {
198 p = p[:numAvail]
199 }
200 numDec, err := Decode(p, d.in[:len(p)*2])
201 d.in = d.in[2*numDec:]
202 if err != nil {
203 d.in, d.err = nil, err
204 }
205
206 if len(d.in) < 2 {
207 return numDec, d.err
208 }
209 return numDec, nil
210 }
211
212
213
214
215 func Dumper(w io.Writer) io.WriteCloser {
216 return &dumper{w: w}
217 }
218
219 type dumper struct {
220 w io.Writer
221 rightChars [18]byte
222 buf [14]byte
223 used int
224 n uint
225 closed bool
226 }
227
228 func toChar(b byte) byte {
229 if b < 32 || b > 126 {
230 return '.'
231 }
232 return b
233 }
234
235 func (h *dumper) Write(data []byte) (n int, err error) {
236 if h.closed {
237 return 0, errors.New("encoding/hex: dumper closed")
238 }
239
240
241
242
243 for i := range data {
244 if h.used == 0 {
245
246
247 h.buf[0] = byte(h.n >> 24)
248 h.buf[1] = byte(h.n >> 16)
249 h.buf[2] = byte(h.n >> 8)
250 h.buf[3] = byte(h.n)
251 Encode(h.buf[4:], h.buf[:4])
252 h.buf[12] = ' '
253 h.buf[13] = ' '
254 _, err = h.w.Write(h.buf[4:])
255 if err != nil {
256 return
257 }
258 }
259 Encode(h.buf[:], data[i:i+1])
260 h.buf[2] = ' '
261 l := 3
262 if h.used == 7 {
263
264 h.buf[3] = ' '
265 l = 4
266 } else if h.used == 15 {
267
268
269 h.buf[3] = ' '
270 h.buf[4] = '|'
271 l = 5
272 }
273 _, err = h.w.Write(h.buf[:l])
274 if err != nil {
275 return
276 }
277 n++
278 h.rightChars[h.used] = toChar(data[i])
279 h.used++
280 h.n++
281 if h.used == 16 {
282 h.rightChars[16] = '|'
283 h.rightChars[17] = '\n'
284 _, err = h.w.Write(h.rightChars[:])
285 if err != nil {
286 return
287 }
288 h.used = 0
289 }
290 }
291 return
292 }
293
294 func (h *dumper) Close() (err error) {
295
296 if h.closed {
297 return
298 }
299 h.closed = true
300 if h.used == 0 {
301 return
302 }
303 h.buf[0] = ' '
304 h.buf[1] = ' '
305 h.buf[2] = ' '
306 h.buf[3] = ' '
307 h.buf[4] = '|'
308 nBytes := h.used
309 for h.used < 16 {
310 l := 3
311 if h.used == 7 {
312 l = 4
313 } else if h.used == 15 {
314 l = 5
315 }
316 _, err = h.w.Write(h.buf[:l])
317 if err != nil {
318 return
319 }
320 h.used++
321 }
322 h.rightChars[nBytes] = '|'
323 h.rightChars[nBytes+1] = '\n'
324 _, err = h.w.Write(h.rightChars[:nBytes+2])
325 return
326 }
327
View as plain text