4
0

hex.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package codec
  2. // hexMap is a precalculated map of hex nibbles
  3. const hexMap = "" +
  4. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  5. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  6. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  7. "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\xff\xff\xff\xff\xff\xff" +
  8. "\xff\x0a\x0b\x0c\x0d\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  9. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  10. "\xff\x0a\x0b\x0c\x0d\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  11. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  12. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  13. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  14. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  15. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  16. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  17. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  18. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
  19. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
  20. // likelyHexChars is a set of characters that you would expect to find at
  21. // least one of in hex encoded data. This risks missing some hex data that
  22. // doesn't contain these characters, but gives you the performance gain of not
  23. // trying to decode a lot of long symbols in code.
  24. var likelyHexChars = make([]bool, 256)
  25. func init() {
  26. for _, c := range `0123456789` {
  27. likelyHexChars[c] = true
  28. }
  29. }
  30. // decodeHex decodes hex data
  31. func decodeHex(encodedValue string) string {
  32. size := len(encodedValue)
  33. // hex should have two characters per byte
  34. if size%2 != 0 {
  35. return ""
  36. }
  37. if !hasByte(encodedValue, likelyHexChars) {
  38. return ""
  39. }
  40. decodedValue := make([]byte, size/2)
  41. for i := 0; i < size; i += 2 {
  42. n1 := hexMap[encodedValue[i]]
  43. n2 := hexMap[encodedValue[i+1]]
  44. if n1|n2 == '\xff' {
  45. return ""
  46. }
  47. b := n1<<4 | n2
  48. if !printableASCII[b] {
  49. return ""
  50. }
  51. decodedValue[i/2] = b
  52. }
  53. return string(decodedValue)
  54. }