Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_hex.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
27#include "nilorea/n_hex.h"
28
29#include "nilorea/n_common.h"
30#include "nilorea/n_log.h"
31#include "nilorea/n_str.h"
32
33#include <ctype.h>
34#include <stdint.h>
35#include <string.h>
36
38static const char n_hex_digits[] = "0123456789abcdef";
39
40/* Map one ASCII hex digit to its 0..15 value, or -1 when it is not a hex digit. */
41static int n_hex_value(int c) {
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;
45 return -1;
46}
47
48N_STR* n_hex_encode(const unsigned char* data, size_t len) {
49 if (!data && len > 0) {
50 n_log(LOG_ERR, "n_hex_encode: NULL data with len %zu", len);
51 return NULL;
52 }
53 if (len > (SIZE_MAX - 1) / 2) {
54 n_log(LOG_ERR, "n_hex_encode: input length %zu too large", len);
55 return NULL;
56 }
57
58 N_STR* out = new_nstr(len * 2 + 1);
59 __n_assert(out, return NULL);
60
61 char* p = out->data;
62 for (size_t i = 0; i < len; i++) {
63 *p++ = n_hex_digits[(data[i] >> 4) & 0x0F];
64 *p++ = n_hex_digits[data[i] & 0x0F];
65 }
66 *p = '\0';
67 out->written = len * 2;
68 return out;
69}
70
71unsigned char* n_hex_decode(const char* hex, size_t* out_len) {
72 if (out_len) *out_len = 0;
73 __n_assert(hex, return NULL);
74
75 size_t hlen = strlen(hex);
76
77 /* first pass: count hex digits and validate every non-space character */
78 size_t ndigits = 0;
79 for (size_t i = 0; i < hlen; i++) {
80 unsigned char c = (unsigned char)hex[i];
81 if (isspace(c)) continue;
82 if (n_hex_value(c) < 0) {
83 n_log(LOG_ERR, "n_hex_decode: invalid hex character 0x%02x at offset %zu", c, i);
84 return NULL;
85 }
86 ndigits++;
87 }
88 if (ndigits % 2 != 0) {
89 n_log(LOG_ERR, "n_hex_decode: odd hex digit count %zu", ndigits);
90 return NULL;
91 }
92
93 size_t blen = ndigits / 2;
94 unsigned char* buf = NULL;
95 Malloc(buf, unsigned char, blen + 1);
96 __n_assert(buf, return NULL);
97
98 /* second pass: pack each hex pair into one byte */
99 size_t bi = 0;
100 int high = -1;
101 for (size_t i = 0; i < hlen; i++) {
102 unsigned char c = (unsigned char)hex[i];
103 if (isspace(c)) continue;
104 int v = n_hex_value(c);
105 if (high < 0) {
106 high = v;
107 } else {
108 buf[bi++] = (unsigned char)((high << 4) | v);
109 high = -1;
110 }
111 }
112 buf[blen] = '\0';
113 if (out_len) *out_len = blen;
114 return buf;
115}
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:204
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:279
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_ERR
error conditions
Definition n_log.h:76
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,...
Definition n_hex.c:71
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.
Definition n_hex.c:48
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
Definition n_str.h:68
char * data
the string
Definition n_str.h:63
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition n_str.c:207
A box including a string and his lenght.
Definition n_str.h:61
Common headers and low-level functions & define.
static int n_hex_value(int c)
Definition n_hex.c:41
static const char n_hex_digits[]
lowercase hexadecimal digit table
Definition n_hex.c:38
Hexadecimal encode/decode helpers.
Generic log system.
N_STR and string function declaration.