Last active
February 26, 2022 14:10
-
-
Save J-Rios/27b25dbc0804e6f6371b8e4a0f90462e to your computer and use it in GitHub Desktop.
C Hexadecimal String To Byte Array Conversion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Libraries */ | |
// Standard libc Library | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdbool.h> | |
/*****************************************************************************/ | |
/* Defines */ | |
// Hexadecimal string max size | |
#define HEX_STR_SIZE 23 | |
// Hexadecimal byte array size | |
#define BYTE_ARRAY_SIZE 11 | |
/*****************************************************************************/ | |
/* Function Prototypes */ | |
/** | |
* @brief Convert an hexadecimal string to uint8_t bytes array. | |
* @param hex_str Hexadecimal string to convert. | |
* @param hex_str_length Length of hexadecimal string. | |
* @param byte_array Converted byte array. | |
* @param byte_array_size Maximum size of byte array. | |
* @return Conversion result success/fail (true/false). | |
*/ | |
bool hex_str_2_byte_array(const char* hex_str, const uint16_t hex_str_length, | |
uint8_t* byte_array, const uint16_t byte_array_size); | |
/** | |
* @brief Convert an hexadecimal character to unsigned integer of 8 bits. | |
* @param c Character to convert. | |
* @param n Converted byte number. | |
* @return Conversion result success/fail (true/false). | |
*/ | |
bool char_2_hex(const char c, uint8_t* n); | |
/*****************************************************************************/ | |
/* Main Function */ | |
int main() | |
{ | |
char hex_str[HEX_STR_SIZE] = "0123456789abcdefABCDEF"; | |
uint8_t byte_array[BYTE_ARRAY_SIZE] = { 0x00 }; | |
bool fail = false; | |
fail = !hex_str_2_byte_array(hex_str, HEX_STR_SIZE-1, | |
byte_array, BYTE_ARRAY_SIZE); | |
if (fail) | |
{ | |
printf("\nConversion Fail\n"); | |
return 1; | |
} | |
printf("\nConversion Success\n"); | |
printf("hex_str: %s\n", hex_str); | |
printf("byte_array: "); | |
for (uint8_t i = 0; i < BYTE_ARRAY_SIZE; i++) | |
printf("%02X", byte_array[i]); | |
printf("\n\n"); | |
return 0; | |
} | |
/*****************************************************************************/ | |
/* Auxiliary Functions */ | |
/** | |
* @details | |
* To make the conversion, it go through each hexadecimal string character and | |
* use the char_2_hex() function on each of it to get the corresponding high | |
* and low nibbles that are merged to compose the hexadecimal byte value. | |
* The hexadecimal string provided must be an even length string and has 2 or | |
* more characters, and the output byte array must has enough size to store | |
* the full conversion of the string (byte_array_size >= (hex_str_length / 2)). | |
*/ | |
bool hex_str_2_byte_array(const char* hex_str, const uint16_t hex_str_length, | |
uint8_t* byte_array, const uint16_t byte_array_size) | |
{ | |
uint8_t n_left_nibble = 0; | |
uint8_t n_right_nibble = 0; | |
// Check for valid str, has 2 or more chars and is not an odd string | |
if (hex_str == NULL) | |
return false; | |
if (hex_str_length < 2) | |
return false; | |
if ((hex_str_length % 2) != 0) | |
return false; | |
// Check if out byte array has enough size to store the conversion | |
// Note that: (hex_str_length >> 1) == (hex_str_length / 2) | |
if (byte_array_size < (hex_str_length >> 1)) | |
return false; | |
// Convert each character of the string | |
uint16_t ii = 0; | |
for (uint16_t i = 0; i < hex_str_length; i = i + 2) | |
{ | |
if (!char_2_hex(hex_str[i], &n_left_nibble)) | |
return false; | |
if (!char_2_hex(hex_str[i+1], &n_right_nibble)) | |
return false; | |
byte_array[ii] = (n_left_nibble << 4) | (n_right_nibble & 0x0f); | |
ii = ii + 1; | |
} | |
return true; | |
} | |
/** | |
* @details | |
* To convert an hexadecimal character into an uint8_t data type, it checks | |
* for expected valid characters (0-9, a-f or A-F) and substract the | |
* corresponding ASCII code offset to point into 0-15 integer value. | |
* Check the ASCII Encode Table: | |
* https://upload.wikimedia.org/wikipedia/commons/1/1b/ASCII-Table-wide.svg | |
*/ | |
bool char_2_hex(const char c, uint8_t* n) | |
{ | |
if ((c >= '0') && (c <= '9')) | |
*n = (uint8_t)(c - '0'); | |
else if ((c >= 'a') && (c <= 'f')) | |
*n = (uint8_t)(c - 'a') + 10; | |
else if ((c >= 'A') && (c <= 'F')) | |
*n = (uint8_t)(c - 'A') + 10; | |
else | |
return false; | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment