Hex.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "util/Hex.h"
  16. #include <stdint.h>
  17. #include <stdbool.h>
  18. static const uint8_t numForAscii[] =
  19. {
  20. 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
  21. 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
  22. 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
  23. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,99,99,99,99,99,99,
  24. 99,10,11,12,13,14,15,99,99,99,99,99,99,99,99,99,
  25. 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
  26. 99,10,11,12,13,14,15,99,99,99,99,99,99,99,99,99,
  27. 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
  28. };
  29. static const char* hexEntities = "0123456789abcdef";
  30. int Hex_encode(uint8_t* output,
  31. const uint32_t outputLength,
  32. const uint8_t* in,
  33. const uint32_t inputLength)
  34. {
  35. if (outputLength < inputLength * 2) {
  36. return Hex_TOO_BIG;
  37. } else if (outputLength > inputLength * 2) {
  38. output[inputLength * 2] = '\0';
  39. }
  40. for (uint32_t i = 0; i < inputLength; i++) {
  41. output[i * 2] = hexEntities[in[i] >> 4];
  42. output[i * 2 + 1] = hexEntities[in[i] & 15];
  43. }
  44. return inputLength * 2;
  45. }
  46. int Hex_decodeByte(const uint8_t highNibble, const uint8_t lowNibble)
  47. {
  48. if ((highNibble & 0x80) | (lowNibble & 0x80)) {
  49. return -1;
  50. }
  51. int high = numForAscii[highNibble];
  52. int low = numForAscii[lowNibble];
  53. return (high + low < 31) ? (high << 4) | low : -1;
  54. }
  55. bool Hex_isHexEntity(const uint8_t character)
  56. {
  57. return !(character & 0x80) && (numForAscii[character] < 99);
  58. }
  59. int Hex_decode(uint8_t* output,
  60. const uint32_t outLength,
  61. const uint8_t* hex,
  62. const uint32_t length)
  63. {
  64. if (length % 1) {
  65. return Hex_BAD_INPUT;
  66. } else if (outLength < (length / 2)) {
  67. return Hex_TOO_BIG;
  68. } else if (outLength > (length / 2)) {
  69. output[length / 2] = '\0';
  70. }
  71. for (uint32_t i = 0; i < length; i += 2) {
  72. int byte = Hex_decodeByte(hex[i], hex[i + 1]);
  73. if (byte == -1) {
  74. return Hex_BAD_INPUT;
  75. }
  76. output[i / 2] = (uint8_t) byte;
  77. }
  78. return length / 2;
  79. }
  80. uint8_t Hex_encodeLowNibble(const uint8_t nibble)
  81. {
  82. return hexEntities[nibble & 15];
  83. }