Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you convert a byte array to a hexadecimal string in C?

Tags:

c

string

hex

I have:

uint8 buf[] = {0, 1, 10, 11}; 

I want to convert the byte array to a string such that I can print the string using printf:

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

and get (the colons aren't necessary):

"00:01:0A:0B" 

Any help would be greatly appreciated.

like image 427
Steve Walsh Avatar asked Jun 15 '11 11:06

Steve Walsh


People also ask

How do you convert a byte array to a hexadecimal string?

To convert byte array to a hex value, we loop through each byte in the array and use String 's format() . We use %02X to print two places ( 02 ) of Hexadecimal ( X ) value and store it in the string st . This is a relatively slower process for large byte array conversion.

How do you turn a byte into a string?

One method is to create a string variable and then append the byte value to the string variable with the help of + operator. This will directly convert the byte value to a string and add it in the string variable. The simplest way to do so is using valueOf() method of String class in java. lang package.

Is byte a hexadecimal?

So a byte -- eight binary digits -- can always be represented by two hexadecimal digits.


2 Answers

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"); 
like image 130
Mark Synowiec Avatar answered Sep 19 '22 08:09

Mark Synowiec


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); } 
like image 31
kriss Avatar answered Sep 22 '22 08:09

kriss