Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019 Nordic Semiconductor ASA |
| 3 | * |
| 4 | * SPDX-License-Identifier: Apache-2.0 |
| 5 | */ |
| 6 | |
| 7 | #include <stddef.h> |
| 8 | #include <zephyr/types.h> |
| 9 | #include <errno.h> |
| 10 | #include <sys/util.h> |
| 11 | |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 12 | int char2hex(char c, uint8_t *x) |
Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 13 | { |
| 14 | if (c >= '0' && c <= '9') { |
| 15 | *x = c - '0'; |
| 16 | } else if (c >= 'a' && c <= 'f') { |
| 17 | *x = c - 'a' + 10; |
| 18 | } else if (c >= 'A' && c <= 'F') { |
| 19 | *x = c - 'A' + 10; |
| 20 | } else { |
| 21 | return -EINVAL; |
| 22 | } |
| 23 | |
| 24 | return 0; |
| 25 | } |
| 26 | |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 27 | int hex2char(uint8_t x, char *c) |
Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 28 | { |
| 29 | if (x <= 9) { |
| 30 | *c = x + '0'; |
Flavio Ceolin | 03d70b2 | 2019-08-10 03:33:00 -0700 | [diff] [blame] | 31 | } else if (x <= 15) { |
Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 32 | *c = x - 10 + 'a'; |
| 33 | } else { |
| 34 | return -EINVAL; |
| 35 | } |
| 36 | |
| 37 | return 0; |
| 38 | } |
| 39 | |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 40 | size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen) |
Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 41 | { |
| 42 | if ((hexlen + 1) < buflen * 2) { |
| 43 | return 0; |
| 44 | } |
| 45 | |
| 46 | for (size_t i = 0; i < buflen; i++) { |
| 47 | if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) { |
| 48 | return 0; |
| 49 | } |
| 50 | if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) { |
| 51 | return 0; |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | hex[2 * buflen] = '\0'; |
| 56 | return 2 * buflen; |
| 57 | } |
| 58 | |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 59 | size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen) |
Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 60 | { |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 61 | uint8_t dec; |
Joakim Andersson | 7a93e94 | 2019-05-28 13:20:35 +0200 | [diff] [blame] | 62 | |
| 63 | if (buflen < hexlen / 2 + hexlen % 2) { |
| 64 | return 0; |
| 65 | } |
| 66 | |
| 67 | /* if hexlen is uneven, insert leading zero nibble */ |
| 68 | if (hexlen % 2) { |
| 69 | if (char2hex(hex[0], &dec) < 0) { |
| 70 | return 0; |
| 71 | } |
| 72 | buf[0] = dec; |
| 73 | hex++; |
| 74 | buf++; |
| 75 | } |
| 76 | |
| 77 | /* regular hex conversion */ |
| 78 | for (size_t i = 0; i < hexlen / 2; i++) { |
| 79 | if (char2hex(hex[2 * i], &dec) < 0) { |
| 80 | return 0; |
| 81 | } |
| 82 | buf[i] = dec << 4; |
| 83 | |
| 84 | if (char2hex(hex[2 * i + 1], &dec) < 0) { |
| 85 | return 0; |
| 86 | } |
| 87 | buf[i] += dec; |
| 88 | } |
| 89 | |
| 90 | return hexlen / 2 + hexlen % 2; |
| 91 | } |