github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/encoding/hex/hex.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package hex implements hexadecimal encoding and decoding. 6 package hex 7 8 import ( 9 "errors" 10 "fmt" 11 "io" 12 "strings" 13 ) 14 15 const hextable = "0123456789abcdef" 16 17 // EncodedLen returns the length of an encoding of n source bytes. 18 // Specifically, it returns n * 2. 19 func EncodedLen(n int) int { return n * 2 } 20 21 // Encode encodes src into EncodedLen(len(src)) 22 // bytes of dst. As a convenience, it returns the number 23 // of bytes written to dst, but this value is always EncodedLen(len(src)). 24 // Encode implements hexadecimal encoding. 25 func Encode(dst, src []byte) int { 26 for i, v := range src { 27 dst[i*2] = hextable[v>>4] 28 dst[i*2+1] = hextable[v&0x0f] 29 } 30 31 return len(src) * 2 32 } 33 34 // ErrLength reports an attempt to decode an odd-length input 35 // using Decode or DecodeString. 36 // The stream-based Decoder returns io.ErrUnexpectedEOF instead of ErrLength. 37 var ErrLength = errors.New("encoding/hex: odd length hex string") 38 39 // InvalidByteError values describe errors resulting from an invalid byte in a hex string. 40 type InvalidByteError byte 41 42 func (e InvalidByteError) Error() string { 43 return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e)) 44 } 45 46 // DecodedLen returns the length of a decoding of x source bytes. 47 // Specifically, it returns x / 2. 48 func DecodedLen(x int) int { return x / 2 } 49 50 // Decode decodes src into DecodedLen(len(src)) bytes, 51 // returning the actual number of bytes written to dst. 52 // 53 // Decode expects that src contains only hexadecimal 54 // characters and that src has even length. 55 // If the input is malformed, Decode returns the number 56 // of bytes decoded before the error. 57 func Decode(dst, src []byte) (int, error) { 58 var i int 59 for i = 0; i < len(src)/2; i++ { 60 a, ok := fromHexChar(src[i*2]) 61 if !ok { 62 return i, InvalidByteError(src[i*2]) 63 } 64 b, ok := fromHexChar(src[i*2+1]) 65 if !ok { 66 return i, InvalidByteError(src[i*2+1]) 67 } 68 dst[i] = (a << 4) | b 69 } 70 if len(src)%2 == 1 { 71 // Check for invalid char before reporting bad length, 72 // since the invalid char (if present) is an earlier problem. 73 if _, ok := fromHexChar(src[i*2]); !ok { 74 return i, InvalidByteError(src[i*2]) 75 } 76 return i, ErrLength 77 } 78 return i, nil 79 } 80 81 // fromHexChar converts a hex character into its value and a success flag. 82 func fromHexChar(c byte) (byte, bool) { 83 switch { 84 case '0' <= c && c <= '9': 85 return c - '0', true 86 case 'a' <= c && c <= 'f': 87 return c - 'a' + 10, true 88 case 'A' <= c && c <= 'F': 89 return c - 'A' + 10, true 90 } 91 92 return 0, false 93 } 94 95 // EncodeToString returns the hexadecimal encoding of src. 96 func EncodeToString(src []byte) string { 97 dst := make([]byte, EncodedLen(len(src))) 98 Encode(dst, src) 99 return string(dst) 100 } 101 102 // DecodeString returns the bytes represented by the hexadecimal string s. 103 // 104 // DecodeString expects that src contains only hexadecimal 105 // characters and that src has even length. 106 // If the input is malformed, DecodeString returns 107 // the bytes decoded before the error. 108 func DecodeString(s string) ([]byte, error) { 109 src := []byte(s) 110 // We can use the source slice itself as the destination 111 // because the decode loop increments by one and then the 'seen' byte is not used anymore. 112 n, err := Decode(src, src) 113 return src[:n], err 114 } 115 116 // Dump returns a string that contains a hex dump of the given data. The format 117 // of the hex dump matches the output of `hexdump -C` on the command line. 118 func Dump(data []byte) string { 119 if len(data) == 0 { 120 return "" 121 } 122 123 var buf strings.Builder 124 // Dumper will write 79 bytes per complete 16 byte chunk, and at least 125 // 64 bytes for whatever remains. Round the allocation up, since only a 126 // maximum of 15 bytes will be wasted. 127 buf.Grow((1 + ((len(data) - 1) / 16)) * 79) 128 129 dumper := Dumper(&buf) 130 dumper.Write(data) 131 dumper.Close() 132 return buf.String() 133 } 134 135 // bufferSize is the number of hexadecimal characters to buffer in encoder and decoder. 136 const bufferSize = 1024 137 138 type encoder struct { 139 w io.Writer 140 err error 141 out [bufferSize]byte // output buffer 142 } 143 144 // NewEncoder returns an io.Writer that writes lowercase hexadecimal characters to w. 145 func NewEncoder(w io.Writer) io.Writer { 146 return &encoder{w: w} 147 } 148 149 func (e *encoder) Write(p []byte) (n int, err error) { 150 for len(p) > 0 && e.err == nil { 151 chunkSize := bufferSize / 2 152 if len(p) < chunkSize { 153 chunkSize = len(p) 154 } 155 156 var written int 157 encoded := Encode(e.out[:], p[:chunkSize]) 158 written, e.err = e.w.Write(e.out[:encoded]) 159 n += written / 2 160 p = p[chunkSize:] 161 } 162 return n, e.err 163 } 164 165 type decoder struct { 166 r io.Reader 167 err error 168 in []byte // input buffer (encoded form) 169 arr [bufferSize]byte // backing array for in 170 } 171 172 // NewDecoder returns an io.Reader that decodes hexadecimal characters from r. 173 // NewDecoder expects that r contain only an even number of hexadecimal characters. 174 func NewDecoder(r io.Reader) io.Reader { 175 return &decoder{r: r} 176 } 177 178 func (d *decoder) Read(p []byte) (n int, err error) { 179 // Fill internal buffer with sufficient bytes to decode 180 if len(d.in) < 2 && d.err == nil { 181 var numCopy, numRead int 182 numCopy = copy(d.arr[:], d.in) // Copies either 0 or 1 bytes 183 numRead, d.err = d.r.Read(d.arr[numCopy:]) 184 d.in = d.arr[:numCopy+numRead] 185 if d.err == io.EOF && len(d.in)%2 != 0 { 186 if _, ok := fromHexChar(d.in[len(d.in)-1]); !ok { 187 d.err = InvalidByteError(d.in[len(d.in)-1]) 188 } else { 189 d.err = io.ErrUnexpectedEOF 190 } 191 } 192 } 193 194 // Decode internal buffer into output buffer 195 if numAvail := len(d.in) / 2; len(p) > numAvail { 196 p = p[:numAvail] 197 } 198 numDec, err := Decode(p, d.in[:len(p)*2]) 199 d.in = d.in[2*numDec:] 200 if err != nil { 201 d.in, d.err = nil, err // Decode error; discard input remainder 202 } 203 204 if len(d.in) < 2 { 205 return numDec, d.err // Only expose errors when buffer fully consumed 206 } 207 return numDec, nil 208 } 209 210 // Dumper returns a WriteCloser that writes a hex dump of all written data to 211 // w. The format of the dump matches the output of `hexdump -C` on the command 212 // line. 213 func Dumper(w io.Writer) io.WriteCloser { 214 return &dumper{w: w} 215 } 216 217 type dumper struct { 218 w io.Writer 219 rightChars [18]byte 220 buf [14]byte 221 used int // number of bytes in the current line 222 n uint // number of bytes, total 223 closed bool 224 } 225 226 func toChar(b byte) byte { 227 if b < 32 || b > 126 { 228 return '.' 229 } 230 return b 231 } 232 233 func (h *dumper) Write(data []byte) (n int, err error) { 234 if h.closed { 235 return 0, errors.New("encoding/hex: dumper closed") 236 } 237 238 // Output lines look like: 239 // 00000010 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d |./0123456789:;<=| 240 // ^ offset ^ extra space ^ ASCII of line. 241 for i := range data { 242 if h.used == 0 { 243 // At the beginning of a line we print the current 244 // offset in hex. 245 h.buf[0] = byte(h.n >> 24) 246 h.buf[1] = byte(h.n >> 16) 247 h.buf[2] = byte(h.n >> 8) 248 h.buf[3] = byte(h.n) 249 Encode(h.buf[4:], h.buf[:4]) 250 h.buf[12] = ' ' 251 h.buf[13] = ' ' 252 _, err = h.w.Write(h.buf[4:]) 253 if err != nil { 254 return 255 } 256 } 257 Encode(h.buf[:], data[i:i+1]) 258 h.buf[2] = ' ' 259 l := 3 260 if h.used == 7 { 261 // There's an additional space after the 8th byte. 262 h.buf[3] = ' ' 263 l = 4 264 } else if h.used == 15 { 265 // At the end of the line there's an extra space and 266 // the bar for the right column. 267 h.buf[3] = ' ' 268 h.buf[4] = '|' 269 l = 5 270 } 271 _, err = h.w.Write(h.buf[:l]) 272 if err != nil { 273 return 274 } 275 n++ 276 h.rightChars[h.used] = toChar(data[i]) 277 h.used++ 278 h.n++ 279 if h.used == 16 { 280 h.rightChars[16] = '|' 281 h.rightChars[17] = '\n' 282 _, err = h.w.Write(h.rightChars[:]) 283 if err != nil { 284 return 285 } 286 h.used = 0 287 } 288 } 289 return 290 } 291 292 func (h *dumper) Close() (err error) { 293 // See the comments in Write() for the details of this format. 294 if h.closed { 295 return 296 } 297 h.closed = true 298 if h.used == 0 { 299 return 300 } 301 h.buf[0] = ' ' 302 h.buf[1] = ' ' 303 h.buf[2] = ' ' 304 h.buf[3] = ' ' 305 h.buf[4] = '|' 306 nBytes := h.used 307 for h.used < 16 { 308 l := 3 309 if h.used == 7 { 310 l = 4 311 } else if h.used == 15 { 312 l = 5 313 } 314 _, err = h.w.Write(h.buf[:l]) 315 if err != nil { 316 return 317 } 318 h.used++ 319 } 320 h.rightChars[nBytes] = '|' 321 h.rightChars[nBytes+1] = '\n' 322 _, err = h.w.Write(h.rightChars[:nBytes+2]) 323 return 324 }