Created
November 6, 2013 18:10
-
-
Save xsleonard/7341172 to your computer and use it in GitHub Desktop.
hex string to byte array, C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unsigned char* hexstr_to_char(const char* hexstr) | |
{ | |
size_t len = strlen(hexstr); | |
IF_ASSERT(len % 2 != 0) | |
return NULL; | |
size_t final_len = len / 2; | |
unsigned char* chrs = (unsigned char*)malloc((final_len+1) * sizeof(*chrs)); | |
for (size_t i=0, j=0; j<final_len; i+=2, j++) | |
chrs[j] = (hexstr[i] % 32 + 9) % 25 * 16 + (hexstr[i+1] % 32 + 9) % 25; | |
chrs[final_len] = '\0'; | |
return chrs; | |
} |
that's nice. how about this one ?
int byteArrayToHexString(uint8_t *byte_array, int byte_array_len,
char *hexstr, int hexstr_len)
{
int off = 0;
int i;
for (i = 0; i < byte_array_len; i ++) {
off += snprintf(hexstr + off, hexstr_len - off,
"%02x", byte_array[i]);
}
hexstr[off] = '\0';
return off;
}
The other way around
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"). Here is a version that does that, also without malloc (since some embedded systems does not implement it (like one I'm currently working with)). Code a little verbose in naming.
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) {
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;
}
@guigarma This is pretty helpful. When checking if the string is valid hex it only checks for capital letters A-F (ASCII 65 - 70). If you use something like sprintf
to produce the hex string then the output will use lowercase letters and the function doesn't work. 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;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is freaking ingenious.