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