views:

144

answers:

3

Hi Stack Overflow,

I have found a whole lot of different solutions to this problem, but not all of them work, and a lot of them seem somewhat hacky and inefficient. Basically I have a string of hexadecimal data (i.e. "55 AA 41 2A 00 94 55 AA BB BB 00 FF") which I would like to convert to raw data. What is the best way to do this?

UPDATE: Vicky's solution worked great for me, but I changed it to work with hexadecimal strings that don't have spaces in between and changed the style a bit.

int i = 0;
char *hexString = "55AA412A009455AABBBB00FF"
char *hexPtr = hexString;
unsigned int *result = calloc(strlen(hexString)/2 + 1, sizeof *result);

while (sscanf(hexPtr, "%02x", &result[i++])) {
    hexPtr += 2;
    if (hexPtr >= hexString + strlen(hexString)) break;
}

return result;
+1  A: 

Did you try sscanf or scanf? This function processes hexadecimal values to and returns "raw data".

ablaeul
+1  A: 

Is the string always the same length?

If so:

char *buf = "55 AA 41 2A 00 94 55 AA BB BB 00 FF";
sscanf(buf, "%x %x %x [repeat as many times as necessary]", &a, &b, &c [etc]);

If not:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, char ** argv)
{
    char *buf = "55 AA 41 2A 00 94 55 AA BB BB 00 FF";
    char *p = buf;
    int i = 0, j;
    unsigned int *result = calloc(strlen(buf)/3 + 1 * sizeof(int), 1);

    if (result)
    {
        while (sscanf(p, "%02x", &result[i++]))
        {
             p += 3;
            if (p > buf + strlen(buf))
            {
             break;
            }
        }

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

        for (j = 0; j < i; j++)
        {
            printf("%02X ", result[j]);
        }

        printf("\n");
    }
}
Vicky
Worked great :)
AriX
The `%02x` conversion specifier requires a pointer to `unsigned int`, but you are passing it a pointer to `unsigned char`. This results in undefined behaviour (in practice, your answer will produce incorrect results on machines that aren't little-endian, and crash on machines with strict alignment requirements).
caf
@caf: Well spotted. I will edit.
Vicky
A: 
#define GETBITS(a) (a < 'A' ? a - '0' : toupper(a) - 'A' + 10)

char *cur;
char data;
for (cur = buffer; *cur; cur++) {
    data = GETBITS(cur[0]) << 4 + GETBITS(cur[1]);
    cur += 2;
    printf("%c", data);
}
printf("\n");
qrdl