42 if (c >=
'0' && c <=
'9')
return c -
'0';
43 if (c >=
'a' && c <=
'f')
return c -
'a' + 10;
44 if (c >=
'A' && c <=
'F')
return c -
'A' + 10;
49 if (!data && len > 0) {
50 n_log(
LOG_ERR,
"n_hex_encode: NULL data with len %zu", len);
53 if (len > (SIZE_MAX - 1) / 2) {
54 n_log(
LOG_ERR,
"n_hex_encode: input length %zu too large", len);
62 for (
size_t i = 0; i < len; i++) {
72 if (out_len) *out_len = 0;
75 size_t hlen = strlen(hex);
79 for (
size_t i = 0; i < hlen; i++) {
80 unsigned char c = (
unsigned char)hex[i];
81 if (isspace(c))
continue;
83 n_log(
LOG_ERR,
"n_hex_decode: invalid hex character 0x%02x at offset %zu", c, i);
88 if (ndigits % 2 != 0) {
89 n_log(
LOG_ERR,
"n_hex_decode: odd hex digit count %zu", ndigits);
93 size_t blen = ndigits / 2;
94 unsigned char* buf = NULL;
95 Malloc(buf,
unsigned char, blen + 1);
101 for (
size_t i = 0; i < hlen; i++) {
102 unsigned char c = (
unsigned char)hex[i];
103 if (isspace(c))
continue;
108 buf[bi++] = (
unsigned char)((high << 4) | v);
113 if (out_len) *out_len = blen;
117size_t n_hex_encode_to(
char* out,
size_t out_size,
const unsigned char* data,
size_t len) {
119 if (!data && len > 0) {
120 n_log(
LOG_ERR,
"n_hex_encode_to: NULL data with len %zu", len);
123 if (len > (SIZE_MAX - 1) / 2) {
124 n_log(
LOG_ERR,
"n_hex_encode_to: input length %zu too large", len);
127 if (out_size < len * 2 + 1) {
128 n_log(
LOG_ERR,
"n_hex_encode_to: buffer %zu too small for %zu bytes", out_size, len);
133 for (
size_t i = 0; i < len; i++) {
141int n_hex_decode_to(
unsigned char* out,
size_t out_size,
const char* hex,
size_t nbytes) {
144 if (out_size < nbytes) {
145 n_log(
LOG_ERR,
"n_hex_decode_to: buffer %zu too small for %zu bytes", out_size, nbytes);
151 for (
size_t i = 0; i < nbytes; i++) {
153 if (hi < 0)
return FALSE;
154 int lo =
n_hex_value((
unsigned char)hex[i * 2 + 1]);
155 if (lo < 0)
return FALSE;
156 out[i] = (
unsigned char)((hi << 4) | lo);
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_ERR
error conditions
unsigned char * n_hex_decode(const char *hex, size_t *out_len)
decode a hex string (ASCII whitespace between digits is ignored) into a freshly allocated,...
size_t n_hex_encode_to(char *out, size_t out_size, const unsigned char *data, size_t len)
encode len bytes of data as lowercase hex into the caller-provided buffer out (needs out_size >= 2*le...
int n_hex_decode_to(unsigned char *out, size_t out_size, const char *hex, size_t nbytes)
decode exactly nbytes bytes from the first 2*nbytes hex digits of hex (case-insensitive,...
N_STR * n_hex_encode(const unsigned char *data, size_t len)
encode len bytes of data as a lowercase hex N_STR (2*len characters); free with free_nstr.
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
A box including a string and his lenght.
Common headers and low-level functions & define.
static int n_hex_value(int c)
static const char n_hex_digits[]
lowercase hexadecimal digit table
Hexadecimal encode/decode helpers.
N_STR and string function declaration.