As far as I know, there's no standard function to do so, but it's simple to achieve in the following manner:

#include <stdio.h>

int main(int argc, char **argv) {
    const char hexstring[] = "DEadbeef10203040b00b1e50", *pos = hexstring;
    unsigned char val[12];

     /* WARNING: no sanitization or error-checking whatsoever */
    for (size_t count = 0; count < sizeof val/sizeof *val; count++) {
        sscanf(pos, "%2hhx", &val[count]);
        pos += 2;
    }

    printf("0x");
    for(size_t count = 0; count < sizeof val/sizeof *val; count++)
        printf("%02x", val[count]);
    printf("\n");

    return 0;
}

Edit

As Al pointed out, in case of an odd number of hex digits in the string, you have to make sure you prefix it with a starting 0. For example, the string "f00f5" will be evaluated as {0xf0, 0x0f, 0x05} erroneously by the above example, instead of the proper {0x0f, 0x00, 0xf5}.

Answer from Michael F on Stack Overflow
Top answer
1 of 16
83

As far as I know, there's no standard function to do so, but it's simple to achieve in the following manner:

#include <stdio.h>

int main(int argc, char **argv) {
    const char hexstring[] = "DEadbeef10203040b00b1e50", *pos = hexstring;
    unsigned char val[12];

     /* WARNING: no sanitization or error-checking whatsoever */
    for (size_t count = 0; count < sizeof val/sizeof *val; count++) {
        sscanf(pos, "%2hhx", &val[count]);
        pos += 2;
    }

    printf("0x");
    for(size_t count = 0; count < sizeof val/sizeof *val; count++)
        printf("%02x", val[count]);
    printf("\n");

    return 0;
}

Edit

As Al pointed out, in case of an odd number of hex digits in the string, you have to make sure you prefix it with a starting 0. For example, the string "f00f5" will be evaluated as {0xf0, 0x0f, 0x05} erroneously by the above example, instead of the proper {0x0f, 0x00, 0xf5}.

2 of 16
25

I found this question by Googling for the same thing. I don't like the idea of calling sscanf() or strtol() since it feels like overkill. I wrote a quick function which does not validate that the text is indeed the hexadecimal presentation of a byte stream, but will handle odd number of hex digits:

uint8_t tallymarker_hextobin(const char * str, uint8_t * bytes, size_t blen)
{
   uint8_t  pos;
   uint8_t  idx0;
   uint8_t  idx1;

   // mapping of ASCII characters to hex values
   const uint8_t hashmap[] =
   {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  !"#$%&'
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ()*+,-./
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
     0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
     0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // @ABCDEFG
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // HIJKLMNO
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PQRSTUVW
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // XYZ[\]^_
     0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // `abcdefg
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // hijklmno
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pqrstuvw
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xyz{|}~.
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // ........
   };

   bzero(bytes, blen);
   for (pos = 0; ((pos < (blen*2)) && (pos < strlen(str))); pos += 2)
   {
      idx0 = (uint8_t)str[pos+0];
      idx1 = (uint8_t)str[pos+1];
      bytes[pos/2] = (uint8_t)(hashmap[idx0] << 4) | hashmap[idx1];
   };

   return(0);
}
🌐
GitHub
gist.github.com › xsleonard › 7341172
hex string to byte array, C · GitHub
I added a small check to fix that. int HexStringToBytes(const char *hexStr, unsigned char *output, unsigned int *outputLen) { size_t len = strlen(hexStr); if (len % 2 != 0) { return -1; } size_t finalLen = len / 2; *outputLen = finalLen; for (size_t inIdx = 0, outIdx = 0; outIdx < finalLen; inIdx += 2, outIdx++) { if ((hexStr[inIdx] - 48) <= 9 && (hexStr[inIdx + 1] - 48) <= 9) { goto convert; } else { if (((hexStr[inIdx] - 65) <= 5 && (hexStr[inIdx + 1] - 65) <= 5) || ((hexStr[inIdx] - 97) <= 5 && (hexStr[inIdx + 1] - 97) <= 5)) { goto convert; } else { *outputLen = 0; return -1; } } convert: output[outIdx] = (hexStr[inIdx] % 32 + 9) % 25 * 16 + (hexStr[inIdx + 1] % 32 + 9) % 25; } output[finalLen] = '\0'; return 0; }
Discussions

How to correctly convert a Hex String to Byte Array in C? - Stack Overflow
I need to convert a string, containing hex values as characters, into a byte array. Although this has been answered already here as the first answer, I get the following error: warning: ISO C90 do... More on stackoverflow.com
🌐 stackoverflow.com
August 16, 2013
c - Convert hex string to string of bytes - Stack Overflow
I need to convert a (potentially very long) string like char * s = "2f0a3f" into the actual bytes it represents, when decoded from the hex representation. Currently I'm doing this, but it feels clu... More on stackoverflow.com
🌐 stackoverflow.com
September 21, 2012
How do you convert a byte array to a hexadecimal string in C? - Stack Overflow
CopyRaw buffer as a hex string: %*ph 00 01 02 ... 3f %*phC 00:01:02: ... :3f %*phD 00-01-02- ... -3f %*phN 000102 ... 3f For printing a small buffers (up to 64 bytes long) as a hex string with certain separator. More on stackoverflow.com
🌐 stackoverflow.com
C help needed. (string to BYTE array)
Unfortunately you will have to convert it manually as you can't 'add 0x' to a string in order to convert it to hex for you. More on reddit.com
🌐 r/learnprogramming
8
2
December 23, 2022
🌐
Programming Idioms
programming-idioms.org › idiom › 176 › hex-string-to-byte-array › 3653 › c
Hex string to byte array, in C
ubyte[] a = s.chunks(2) .map!(digits => digits.to!ubyte) .array; ... integer(kind=c_int8_t), dimension(:), allocatable :: a allocate (a(len(s)/2)) read(unit=s,fmt='(*(Z2))') a ... s .split('') .map((el, ix, arr) => ix % 2 ? null : el + arr[ix + 1]) .filter(el => el !== null) .map(x => parseInt(x, 16)) ... int i, n = s.length(); byte a[] = new byte[n / 2]; for (i = 0; i < n; i = i + 2) a[i / 2] = (byte) fromHexDigits(s, i, i + 2); ... public static byte[] hexToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; }
🌐
ColinPaice
colinpaice.blog › 2023 › 06 › 06 › easy-question-hard-answer-how-to-i-convert-a-hex-string-to-hex-byte-string-in-c
Easy question – hard answer, how to I convert a hex string to hex byte string in C?
June 6, 2023 - It takes a formatting string and converts from printable to internal format. ... Would processes the characters in the data pointed to by pData and covert them, treating hen as hex data, to an integer &i.
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 150170-how-change-hex-string-byte-array.html
How to change HEX String to Byte Array
August 12, 2012 - Just use a temporary variable with sscanf, and cast over to unsigned char or char, whichever is right, when you put it into the byte string. I am fairly sure this was completely ignored in your attempt and contributed to things being very wrong. Last edited by whiteflags; 08-13-2012 at 12:07 AM.
Top answer
1 of 7
5
/* allocate the buffer */
char * buffer = malloc((strlen(s) / 2) + 1);

char *h = s; /* this will walk through the hex string */
char *b = buffer; /* point inside the buffer */

/* offset into this string is the numeric value */
char xlate[] = "0123456789abcdef";

for ( ; *h; h += 2, ++b) /* go by twos through the hex string */
   *b = ((strchr(xlate, *h) - xlate) * 16) /* multiply leading digit by 16 */
       + ((strchr(xlate, *(h+1)) - xlate));

Edited to add

In 80x86 assembly lanugage, the heart of strchr() is basically one instruction - it doesn't loop.

Also: this does no bounds checking, won't work with Unicode console input, and will crash if passed an invalid character.

Also: thanks to those who pointed out some serious typos.

2 of 7
4

Not that it'd make much difference, but I'd go with a multiplication over a division. Also it's worth splitting out the digit code, as you might want to port it to a platform where a-f are not adjacent in the character set (only joking!)

  inline int digittoint(char d) {
    return ((d) <= '9' ? (d) - '0' : (d) - 'a' + 10);
  }
  #define digittoint(d) ((d) <= '9' ? (d) - '0' : (d) - 'a' + 10)

  size_t hexlength = strlen(s);
  size_t binlength = hexlength / 2;

  unsigned char * buffer = malloc(binlength);
  long i = 0;
  char a, b;

  for (; i < binlength; ++i) {
    a = s[2 * i + 0]; b = s[2 * i + 1];
    buffer[i] = (digittoint(a) << 4) | digittoint(b);
  }

I've fixed a bug in your digit-to-int implementation, and replaced the + with bitwise or on the grounds that it better expresses your intent.

You can then experiment to find the best implementation of digittoint - conditional arithmetic as above, strspn, or a lookup table.

Here's a possible branchless implementation that - bonus! - works on uppercase letters:

inline int digittoint(char d) {
    return (d & 0x1f) + ((d >> 6) * 0x19) - 0x10;
}
Find elsewhere
🌐
GitHub
gist.github.com › vi › dd3b5569af8a26b97c8e20ae06e804cb
Hex string to byte buffer in C · GitHub
Hex string to byte buffer in C. GitHub Gist: instantly share code, notes, and snippets.
🌐
Hex to String
hextostring.com › post › chextostring
Convert Hexadecimal to String in C (Parse Bytes Safely) | Hex to String Guides
July 22, 2026 - In C, “hex to string” usually means one of two jobs: Hex text → bytes (parse "48656c6c6f" into a buffer), then optionally treat those bytes as a C string.
Top answer
1 of 16
123
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);

For a more generic way:

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) printf(":");
    printf("%02X", buf[i]);
}
printf("\n");

To concatenate to a string, there are a few ways you can do this. I'd probably keep a pointer to the end of the string and use sprintf. You should also keep track of the size of the array to make sure it doesn't get larger than the space allocated:

int i;
char* buf2 = stringbuf;
char* endofbuf = stringbuf + sizeof(stringbuf);
for (i = 0; i < x; i++)
{
    /* i use 5 here since we are going to add at most 
       3 chars, need a space for the end '\n' and need
       a null terminator */
    if (buf2 + 5 < endofbuf)
    {
        if (i > 0)
        {
            buf2 += sprintf(buf2, ":");
        }
        buf2 += sprintf(buf2, "%02X", buf[i]);
    }
}
buf2 += sprintf(buf2, "\n");
2 of 16
47

For completude, you can also easily do it without calling any heavy library function (no snprintf, no strcat, not even memcpy). It can be useful, say if you are programming some microcontroller or OS kernel where libc is not available.

Nothing really fancy you can find similar code around if you google for it. Really it's not much more complicated than calling snprintf and much faster.

#include <stdio.h>

int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    int i = 0;
    for(; i < sizeof(buf)-1; ++i){
        *pout++ = hex[(*pin>>4)&0xF];
        *pout++ = hex[(*pin++)&0xF];
        *pout++ = ':';
    }
    *pout++ = hex[(*pin>>4)&0xF];
    *pout++ = hex[(*pin)&0xF];
    *pout = 0;

    printf("%s\n", str);
}

Here is another slightly shorter version. It merely avoid intermediate index variable i and duplicating laste case code (but the terminating character is written two times).

#include <stdio.h>
int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    for(; pin < buf+sizeof(buf); pout+=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
    }
    pout[-1] = 0;

    printf("%s\n", str);
}

Below is yet another version to answer to a comment saying I used a "trick" to know the size of the input buffer. Actually it's not a trick but a necessary input knowledge (you need to know the size of the data that you are converting). I made this clearer by extracting the conversion code to a separate function. I also added boundary check code for target buffer, which is not really necessary if we know what we are doing.

#include <stdio.h>

void tohex(unsigned char * in, size_t insz, char * out, size_t outsz)
{
    unsigned char * pin = in;
    const char * hex = "0123456789ABCDEF";
    char * pout = out;
    for(; pin < in+insz; pout +=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
        if (pout + 3 - out > outsz){
            /* Better to truncate output string than overflow buffer */
            /* it would be still better to either return a status */
            /* or ensure the target buffer is large enough and it never happen */
            break;
        }
    }
    pout[-1] = 0;
}

int main(){
    enum {insz = 4, outsz = 3*insz};
    unsigned char buf[] = {0, 1, 10, 11};
    char str[outsz];
    tohex(buf, insz, str, outsz);
    printf("%s\n", str);
}
🌐
Reddit
reddit.com › r/learnprogramming › c help needed. (string to byte array)
r/learnprogramming on Reddit: C help needed. (string to BYTE array)
December 23, 2022 -

Hello:

Would someone please point me to the solution for this? ( I am a C newbie )

I am running a C program with an Input argument .

This argument (argv[1]) is a string containing "1112131415e0",

I need to have this string stored in a BYTE array (container1) such that is the same as if I wrote :

BYTE container1[] = { 0x11, 0x12, 0x13, 0x14,0x14,0xe0}

I don't want to convert 11 to hex.. I just want to add the 0x and have it stored.

Thanks a lot!

🌐
Arduino Forum
forum.arduino.cc › projects › programming
Convert hex string to bytes and vice versa - Programming - Arduino Forum
May 22, 2019 - Hello, My Arduino program involves SHA256 hashing, using this cryptography library https://rweather.github.io/arduinolibs/crypto.html For that purpose I'm using some strings of hex characters. A simple version of my program is as follows: char hex[256]; char *btoh(char *dest, uint8_t *src, int len) { char *d = dest; while( len-- ) sprintf(d, "x", (unsigned char)*src++), d += 2; return dest; } char* h(String input) { SHA256 hash; uint8_t result[32]; hash.reset(); hash.update(...
Top answer
1 of 3
2

There are indeed many methods (and they all work if done right).

Is it always a lenght of 8 ? That means it is 32-bit unsigned long number. The strtoul can convert it to a long. Use '16' for the base. If you need the seperate numbers, you can shift the unsigned long and convert to bytes or use a union.

It is also possible to do with a for statement can convert each character of the input to a value: forum.arduino.cc: convert HEX (ASCII) to a DEC int

[ADDED]
Thank you @goddland_16 for providing a full sketch. I could not stay behind and wrote a sketch with strtoul.

char *CardNumber = "B763AB23";
byte CardNumberByte[4];

void setup() 
{
  Serial.begin(9600);
  Serial.println("With strtoul");

  // Use 'nullptr' or 'NULL' for the second parameter.
  unsigned long number = strtoul( CardNumber, nullptr, 16);

  for(int i=3; i>=0; i--)    // start with lowest byte of number
  {
    CardNumberByte[i] = number & 0xFF;  // or: = byte( number);
    number >>= 8;            // get next byte into position
  }

  for(int i=0; i<4; i++)
  {
    Serial.print("0x");
    Serial.println(CardNumberByte[i], HEX);
  }
}

void loop() 
{
}
2 of 3
0

Here is a simple solution to your question. I took each character, checked against its hexadecimal character and returned as a combination.

char CardNumber[] = "B763AB23";
byte CardNumberByte[4];

void setup() {
  Serial.begin(9600);
}

void loop() {
  for(char i = 0; i < 4; i++)
{
  byte extract;
  char a = CardNumber[2*i];
  char b = CardNumber[2*i + 1];
  extract = convertCharToHex(a)<<4 | convertCharToHex(b);
  CardNumberByte[i] = extract;
  Serial.println(CardNumberByte[i], HEX);
}

  while(1);
}



char convertCharToHex(char ch)
{
  char returnType;
  switch(ch)
  {
    case '0':
    returnType = 0;
    break;
    case  '1' :
    returnType = 1;
    break;
    case  '2':
    returnType = 2;
    break;
    case  '3':
    returnType = 3;
    break;
    case  '4' :
    returnType = 4;
    break;
    case  '5':
    returnType = 5;
    break;
    case  '6':
    returnType = 6;
    break;
    case  '7':
    returnType = 7;
    break;
    case  '8':
    returnType = 8;
    break;
    case  '9':
    returnType = 9;
    break;
    case  'A':
    returnType = 10;
    break;
    case  'B':
    returnType = 11;
    break;
    case  'C':
    returnType = 12;
    break;
    case  'D':
    returnType = 13;
    break;
    case  'E':
    returnType = 14;
    break;
    case  'F' :
    returnType = 15;
    break;
    default:
    returnType = 0;
    break;
  }
  return returnType;
}
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Hex String to Byte Array - Programming - Arduino Forum
December 24, 2018 - Hello, I'm having trouble figuring out how to convert a hex string such as "A489B1" into an array like [0xA4, 0x89, 0xB1]. Anyone have any ideas? Thank you!
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › how-to-convert-hex-string-to-byte-array-in-cpp
How to Convert Hex String to Byte Array in C++? - GeeksforGeeks
March 4, 2024 - Input: Hex String : "2f4a33" Output: Byte Array : 47 74 51 Explanation: Hex String: "2f" Therefore, "2f" is converted to 47.