You can't fit 5 bytes worth of data into a 4 byte array; that leads to buffer overflows.

If you have the hex digits in a string, you can use sscanf() and a loop:

#include <stdio.h>
#include <ctype.h>

int main()
{
    const char *src = "0011223344";
    char buffer[5];
    char *dst = buffer;
    char *end = buffer + sizeof(buffer);
    unsigned int u;

    while (dst < end && sscanf(src, "%2x", &u) == 1)
    {
        *dst++ = u;
        src += 2;
    }

    for (dst = buffer; dst < end; dst++)
        printf("%d: %c (%d, 0x%02x)\n", dst - buffer,
               (isprint(*dst) ? *dst : '.'), *dst, *dst);

    return(0);
}

Note that printing the string starting with a zero-byte requires care; most operations terminate on the first null byte. Note that this code did not null-terminate the buffer; it is not clear whether null-termination is desirable, and there isn't enough space in the buffer I declared to add a terminal null (but that is readily fixed). There's a decent chance that if the code was packaged as a subroutine, it would need to return the length of the converted string (though you could also argue it is the length of the source string divided by two).

Answer from Jonathan Leffler on Stack Overflow
Top answer
1 of 11
18

You can't fit 5 bytes worth of data into a 4 byte array; that leads to buffer overflows.

If you have the hex digits in a string, you can use sscanf() and a loop:

#include <stdio.h>
#include <ctype.h>

int main()
{
    const char *src = "0011223344";
    char buffer[5];
    char *dst = buffer;
    char *end = buffer + sizeof(buffer);
    unsigned int u;

    while (dst < end && sscanf(src, "%2x", &u) == 1)
    {
        *dst++ = u;
        src += 2;
    }

    for (dst = buffer; dst < end; dst++)
        printf("%d: %c (%d, 0x%02x)\n", dst - buffer,
               (isprint(*dst) ? *dst : '.'), *dst, *dst);

    return(0);
}

Note that printing the string starting with a zero-byte requires care; most operations terminate on the first null byte. Note that this code did not null-terminate the buffer; it is not clear whether null-termination is desirable, and there isn't enough space in the buffer I declared to add a terminal null (but that is readily fixed). There's a decent chance that if the code was packaged as a subroutine, it would need to return the length of the converted string (though you could also argue it is the length of the source string divided by two).

2 of 11
3

I would do something like this;

// Convert from ascii hex representation to binary
// Examples;
//   "00" -> 0
//   "2a" -> 42
//   "ff" -> 255
// Case insensitive, 2 characters of input required, no error checking
int hex2bin( const char *s )
{
    int ret=0;
    int i;
    for( i=0; i<2; i++ )
    {
        char c = *s++;
        int n=0;
        if( '0'<=c && c<='9' )
            n = c-'0';
        else if( 'a'<=c && c<='f' )
            n = 10 + c-'a';
        else if( 'A'<=c && c<='F' )
            n = 10 + c-'A';
        ret = n + ret*16;
    }
    return ret;
}

int main()
{
    const char *in = "0011223344";
    char out[5];
    int i;

    // Hex to binary conversion loop. For example;
    // If in="0011223344" set out[] to {0x00,0x11,0x22,0x33,0x44}
    for( i=0; i<5; i++ )
    {
        out[i] = hex2bin( in );
        in += 2;
    }
    return 0;
}
🌐
Ondrovo
bits.ondrovo.com › hexc.html
Hex to C array - Ondrovo.com
Paste hex string. Characters outside 0-9a-fA-F and anything after | is discarded (hexdump). Hex digit count must be even.
🌐
GitHub
gist.github.com › xsleonard › 7341172
hex string to byte array, C · GitHub
char* barray2hexstr (const unsigned char* data, size_t datalen) { size_t final_len = datalen * 2; char* chrs = (unsigned char *) malloc((final_len + 1) * sizeof(*chrs)); unsigned int j = 0; for(j = 0; j<datalen; j++) { chrs[2*j] = (data[j]>>4)+48; chrs[2*j+1] = (data[j]&15)+48; if (chrs[2*j]>57) chrs[2*j]+=7; if (chrs[2*j+1]>57) chrs[2*j+1]+=7; } chrs[2*j]='\0'; return chrs; } ... It is very nice, but it does not check if the hex string is an actual hex string (for example "3FZP").
Top answer
1 of 4
6
char * print_hex(const unsigned char *hash, const hashid type)
{
    const char lookupTable[]="0123456789abcdef";
    const size_t hashLength=mhash_get_block_size(type);
    size_t i;
    char * out=malloc(hashLength*2+1);
    if(out==NULL)
        return NULL;
    for (i = 0; i < hashLength; i++)
    {
        out[i*2]=lookupTable[hash[i]>>4];
        out[i*2+1]=lookupTable[hash[i]&0xf];
    }
    out[hashLength*2]=0;
    return out;
}

Obviously the caller is responsible for freeing the returned string.

Still, as @K-Ballo correctly said in his answer, you don't need to convert to string form two hashes to compare them, all you need in that case is just a memcmp.

int compare_hashes(const unsigned char * hash1, const hashid hash1type, const unsigned char * hash2, const hashid hash2type)
{
    if(hash1type!=hash2type)
        return 0;
    return memcmp(hash1, hash2, mhash_get_block_size(hash1type))==0;
}
2 of 4
4

How can I modify this function so that it returns a string?

You can print to a string variable using sprintf. I assume the hash size is fixed, so you know the size of your string would be number-of-chars-in-hash * 2 + 1. How to return that information is a typical problem in C, you can either return a malloced string that the user must then remember to free, or return a static string that will get replaced with the next call to the function (and makes the function non-reentrable). Personally I tend to avoid returning strings, instead having the function take a char* destination and a size.

(The goal being that I can compare the 2 values later)

Just compare the two hash variables in its raw form, you don't need strings for that.

🌐
Stack Overflow
stackoverflow.com › questions › 26411447 › how-to-convert-hex-string-to-char-array-of-hex-in-c-c
How to convert hex string to char array of hex in C/C++ - Stack Overflow
October 16, 2014 - takes pointer to the input std::string hexString creates and returns unsigned char array as well as count of elements in the array.
🌐
Devcoons
devcoons.com › convert-a-char-array-of-hex-to-ascii-in-c
Convert a char array of HEX to ASCII in C – Devcoons
void hex_to_string(uint8_t* msg, size_t msg_sz, uint8_t* hex, size_t hex_sz) { memset(msg, '\0', msg_sz); if (hex_sz % 2 != 0 || hex_sz/2 >= msg_sz) return; for (int i = 0; i < hex_sz; i+=2) { uint8_t msb = (hex[i+0] <= '9' ? hex[i+0] - '0' : (hex[i+0] & 0x5F) - 'A' + 10); uint8_t lsb = (hex[i+1] ...
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Hex value in string to char array/data array - Programming - Arduino Forum
September 22, 2021 - Hello, I was unable to figure out how to transfer a hex value in string to char array. I have; String l = "731c8080"; // these value changes frequently in the loop String m = "58ed12a5" / /these value changes frequently in the loop char buf[8]; Now I need like this: buf[0] = 0x73; // buf[ ] should be updated frequently based on the "l" and "m" values buf[1] = 0x1c; buf[2] = 0x80; buf[3] = 0x80; buf[4] = 0x58; buf[5] = 0xed; buf[6] = 0x12; buf[7] = 0xa5; Can i get some solution
Find elsewhere
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 176665-convert-hex-byte-array-hex-char*.html
Convert hex byte array to hex char*
November 1, 2018 - You can malloc exactly the right amount of space at the beginning, since you know you'll need 2n+1 bytes to store the string. [fn 1]If for some reason you're going to be doing this a zillion times and you don't want to call sprintf all that time, or you just think it would impress people, you can try to use a hash-table of characters and use the byte (or some bit-masked version of the byte) as an index to grab each character/pair of characters and copy them into your buffer.
🌐
Programming Idioms
programming-idioms.org › idiom › 176 › hex-string-to-byte-array › 3653 › c
Hex string to byte array, in C
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; } ... Do you know the best way to do this in your language ? New implementation... ... const char* hexstring = "deadbeef"; size_t length = sizeof(hexstring); unsigned char bytearray[length / 2]; for (size_t i = 0, j = 0; i < (length / 2); i++, j += 2) bytearray[i] = (hexstring[j] % 32 + 9) % 25 * 16 + (hexstring[j+1] % 32 + 9) % 25;
🌐
Tomeko
tomeko.net › online_tools › ascii.php
ASCII to C-like array converter
See also: bin2hex.exe for Windows and bin2hex for Linux (source code).
🌐
Agnostic Development
agnosticdev.com › blog-entry › c › testing-and-converting-hexadecimal-data-c
Testing and Converting Hexadecimal Data in C | Agnostic Development
November 24, 2017 - In researching the problem I found out that C has a very nice solution to this problem and that was to use sprintf to convert the buffer of hexadecimal data to a char array using the %x formatter tag to signify that we were in fact working with ...
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Splitting string to char array and byte array + hex to bytes - Programming - Arduino Forum
March 20, 2016 - I have a string address included hex-values. String address = "28 A8 FB 13 5 0 0 0 B0"; Question: How can I split it to char array? And char-values to Byte-array? char *arrayc; or char arrayc = new char[30]; array…
🌐
LinuxQuestions.org
linuxquestions.org › questions › programming-9 › how-to-define-hex-character-array-in-c-668213
How to define hex character array in C?
September 7, 2008 - Hi group, I have a simple question. I want to define a hex character array in C, but I don't want to have to define the elements one at a time.
🌐
CodeProject
codeproject.com › Questions › 5263050 › How-to-convert-char-array-to-a-byte-array-in-C-pro
How to convert char array to a byte array in C program
March 10, 2021 - Disclaimer: References to any specific company, product or services on this Site are not controlled by GoDaddy.com LLC and do not constitute or imply its association with or endorsement of third party advertisers
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);
}
🌐
DaniWeb
daniweb.com › programming › software-development › threads › 179960 › convert-char-to-hex
Convert char to hex | DaniWeb
March 5, 2009 - Transferring them to another (unsigned char) array will not really change anything. You should post what code you have to clarify your question. (BTW, 0x03 is not the hex code for the character '3', it's 0x33.) ... Assuming that you want to print out or store the 8bit hex values of each character of the input string I am giving these guidelines.
🌐
Stack Overflow
stackoverflow.com › questions › 28501325 › hex-string-to-char-array-c
Hex String to char* array C++ - Stack Overflow
Copy#include <iostream> #include <algorithm> using namespace std; char* hextostr(const std::string& hexStr) { const char* const hex = "0123456789ABCDEF"; size_t len = hexStr.length(); int k=0; if (len & 1) return NULL; char* output = new char[(len/2)+1]; for (size_t i = 0; i < len; i += 2) { char a,b; a = hexStr[i]; const char* p = std::lower_bound(hex, hex + 16, a); if (*p != a) return NULL; b = hexStr[i + 1]; const char* q = std::lower_bound(hex, hex + 16, b); if (*q != b) return NULL; output[k++] = ((p - hex) << 4) | (q - hex); } output[k] = '\0'; return output; }