how can I convert a hex string to a uint8_t array?
My string is 02012B1530A6E3958A98530031902003876940000000000CDF9844173BE512AFFFFFFE11DBBA1F00079387800E13012E11FC017FFFFFFFFE39C10F40
and I want to convert it into this array:
uint8_t array_uint[] = {0x02, 0x01, 0x2B, 0x15, 0x30, 0xA6, 0xE3, 0x95, 0x8A, 0x98, 0x53, 0x00, 0x31, 0x90, 0x20, 0x03, 0x87, 0x69, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xDF, 0x98, 0x44, 0x17, 0x3B, 0xE5, 0x12, 0xAF, 0xFF, 0xFF, 0xFE, 0x11, 0xDB, 0xBA, 0x1F, 0x00, 0x07, 0x93, 0x87, 0x80, 0x0E, 0x13, 0x01, 0x2E, 0x11, 0xFC, 0x01, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x39, 0xC1, 0x0F, 0x40};
Thank you for your help!
You can use sscanf()
to convert 2 bytes at a time from the source string into the destination array:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
size_t i;
int value;
for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) {
dest[i] = value;
}
return i;
}
Note however that this approach may be inefficient, with a quadratic time complexity, on architectures where the standard library computes the length of the source string for each call to sscanf()
. Using an intermediary array solves this problem:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
char buf[3];
size_t i;
int value;
for (i = 0; i < count && *src; i++) {
buf[0] = *src++;
buf[1] = '\0';
if (*src) {
buf[1] = *src++;
buf[2] = '\0';
}
if (sscanf(buf, "%x", &value) != 1)
break;
dest[i] = value;
}
return i;
}
Storing the conversion result directly into the dest
array is easy:
#include <stdint.h>
#include <stdio.h>
size_t convert_hex(uint8_t *dest, size_t count, const char *src) {
char buf[3];
size_t i;
for (i = 0; i < count && *src; i++) {
buf[0] = *src++;
buf[1] = '\0';
if (*src) {
buf[1] = *src++;
buf[2] = '\0';
}
if (sscanf(buf, "%hhx", &dest[i]) != 1)
break;
}
return i;
}
Purists may argue that %hhx
expects a pointer to an unsigned char
instead of a uint8_t
so the format should be "%"SCNx8
or "%2"SCNx8
, defined in <inttypes.h>
, but these alternatives are less readable and unnecessary as type uint8_t
is always identical to type unsigned char
on architectures where it is defined.