hex.mx raw
1 // Package helpers provides utility functions for smesh.
2 package helpers
3
4 const hexChars = "0123456789abcdef"
5
6 // HexEncode encodes bytes to lowercase hex string.
7 func HexEncode(b []byte) string {
8 out := []byte{:len(b)*2}
9 for i, v := range b {
10 out[i*2] = hexChars[v>>4]
11 out[i*2+1] = hexChars[v&0x0f]
12 }
13 return string(out)
14 }
15
16 // HexDecode decodes a hex string to bytes. Returns nil on invalid input.
17 func HexDecode(s string) []byte {
18 if len(s)%2 != 0 {
19 return nil
20 }
21 out := []byte{:len(s)/2}
22 for i := 0; i < len(s); i += 2 {
23 hi := hexVal(s[i])
24 lo := hexVal(s[i+1])
25 if hi < 0 || lo < 0 {
26 return nil
27 }
28 out[i/2] = byte(hi<<4 | lo)
29 }
30 return out
31 }
32
33 // HexDecode32 decodes a 64-char hex string to [32]byte.
34 // Returns zero and false on invalid input.
35 func HexDecode32(s string) (out [32]byte, ok bool) {
36 if len(s) != 64 {
37 return out, false
38 }
39 for i := 0; i < 32; i++ {
40 hi := hexVal(s[i*2])
41 lo := hexVal(s[i*2+1])
42 if hi < 0 || lo < 0 {
43 return out, false
44 }
45 out[i] = byte(hi<<4 | lo)
46 }
47 return out, true
48 }
49
50 func hexVal(c byte) int {
51 switch {
52 case c >= '0' && c <= '9':
53 return int(c - '0')
54 case c >= 'a' && c <= 'f':
55 return int(c - 'a' + 10)
56 case c >= 'A' && c <= 'F':
57 return int(c - 'A' + 10)
58 default:
59 return -1
60 }
61 }
62