Skip to content

Instantly share code, notes, and snippets.

@J-Rios
Last active February 26, 2022 14:10
Show Gist options
  • Save J-Rios/27b25dbc0804e6f6371b8e4a0f90462e to your computer and use it in GitHub Desktop.
Save J-Rios/27b25dbc0804e6f6371b8e4a0f90462e to your computer and use it in GitHub Desktop.
C Hexadecimal String To Byte Array Conversion
/* 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