xref: /spdk/lib/util/hexlify.c (revision 45a053c5777494f4e8ce4bc1191c9de3920377f7)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/hexlify.h"
7 #include "spdk/log.h"
8 
9 static inline int
10 __c2v(char c)
11 {
12 	if ((c >= '0') && (c <= '9')) {
13 		return c - '0';
14 	}
15 	if ((c >= 'a') && (c <= 'f')) {
16 		return c - 'a' + 10;
17 	}
18 	if ((c >= 'A') && (c <= 'F')) {
19 		return c - 'A' + 10;
20 	}
21 	return -1;
22 }
23 
24 static inline signed char
25 __v2c(int c)
26 {
27 	const char hexchar[] = "0123456789abcdef";
28 	if (c < 0 || c > 15) {
29 		return -1;
30 	}
31 	return hexchar[c];
32 }
33 
34 char *
35 spdk_hexlify(const char *bin, size_t len)
36 {
37 	char *hex, *phex;
38 
39 	hex = malloc((len * 2) + 1);
40 	if (hex == NULL) {
41 		return NULL;
42 	}
43 	phex = hex;
44 	for (size_t i = 0; i < len; i++) {
45 		signed char c0 = __v2c((bin[i] >> 4) & 0x0f);
46 		signed char c1 = __v2c((bin[i]) & 0x0f);
47 		if (c0 < 0 || c1 < 0) {
48 			assert(false);
49 			free(hex);
50 			return NULL;
51 		}
52 		*phex++ = c0;
53 		*phex++ = c1;
54 	}
55 	*phex = '\0';
56 	return hex;
57 }
58 
59 char *
60 spdk_unhexlify(const char *hex)
61 {
62 	char *res, *pres;
63 	size_t len = strlen(hex);
64 
65 	if (len % 2 != 0) {
66 		SPDK_ERRLOG("Invalid hex string len %d. It must be mod of 2.\n", (int)len);
67 		return NULL;
68 	}
69 	res = malloc(len / 2);
70 	if (res == NULL) {
71 		return NULL;
72 	}
73 	pres = res;
74 	for (size_t i = 0; i < len; i += 2) {
75 		int v0 = __c2v(hex[i]);
76 		int v1 = __c2v(hex[i + 1]);
77 		if (v0 < 0 || v1 < 0) {
78 			SPDK_ERRLOG("Invalid hex string \"%s\"\n", hex);
79 			free(res);
80 			return NULL;
81 		}
82 		*pres++ = (v0 << 4) + v1;
83 	}
84 	return res;
85 }
86