A method of converting hex and original string / array in C language for MCU

Time:2021-4-15

The original text is published in: https://www.chenxublog.com/2020/03/08/c-fast-convert-hex-char-array.html

Blog park is only for archiving, if there is room for optimization, it will not be corrected later

reason

The reason is that last night someone in the group was discussing how to convert a string into a stringHEXThe method is the best. In the end, which method is the most efficient. After all, this code is to run on MCU, considering the optimal solution of time and space at the same time.

Of course, the discussion is fruitful, and the specific implementation method and code are shown below.

Conversion of char array to hex string

example:

The following quantities will be added

char str[] = "12345";
char data[] = {1,2,3,4,5,0xff};

Turn into

"313233343500"
"0102030405FF"

This is the result

This is actually very simple. If you want to pursue speed, just look up the table

from0-16corresponding0-FThen:

const char hex_table[] = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};

Then take them out one by one and spell them to the corresponding position

void to_hex(char *s, int l, char *d)
{
    while(l--)
    {
        *(d+2*l+1) = hex_table[(*(s+l))&0x0f];
        *(d+2*l) = hex_table[(*(s+l))>>4];
    }
}

The complete test code is as follows:

#include 
const char hex_table[] = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
void to_hex(char *s, int l, char *d)
{
    while(l--)
    {
        *(d+2*l+1) = hex_table[(*(s+l))&0x0f];
        *(d+2*l) = hex_table[(*(s+l))>>4];
    }
}
int main () {
    char s[]= "1234";
    char d[9];
    d[8] = '
#include 
const char hex_table[] = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
void to_hex(char *s, int l, char *d)
{
while(l--)
{
*(d+2*l+1) = hex_table[(*(s+l))&0x0f];
*(d+2*l) = hex_table[(*(s+l))>>4];
}
}
int main () {
char s[]= "1234";
char d[9];
d[8] = '\0';
to_hex(s,4,d);
printf("%s",d);
return 0;
}
'; to_hex(s,4,d); printf("%s",d); return 0; }

Output results:31323334

Hex string to numeric array

example:

Will be similar"AAbb2fFF"The quantity is converted into{0xAA,0xBB,0x2F,0xff}This is the result

If you still use the look-up table, this ROM will waste a lot of space, and all the look-up table methods will be rejected directly (if it’s PC, it can be used to pursue the ultimate speed).

At the same time, in order to be universal, the code needs to be compatible with both case and input data

When studying the structure of data carefully, I found a rule:

In ASCII0-9Corresponding0x30-0x39
In ASCIIA-FCorresponding0x41-0x46
In ASCIIa-fCorresponding0x61-0x66

That is to say, as long as this character is greater than0x39Then it must be a letter. At the same time, it can be found from the analysis above,If the character is a letter, no matter in upper case or lower case, you only need to look down four digits to directly determine the number represented by the character

The specific logic is as follows:

Determine whether this character is greater than0x39

If not, take the lower four digits of the character as the result

If it is, it’s a letter. Add his lower four digits9This is the desired result

The specific implementation code is also as follows:

void from_hex(char *s, int l, char *d)
{
    while(l--)
    {
        char* p = s+l;
        char* p2 = p-1;
        *(d+l/2) =
        ( (*p>'9'? *p+9 : *p) & 0x0f ) |
        ( (*p2>'9'? *p2+9 : *p2) << 4 );
        l--;
    }
}

Complete test code:

#include 

void from_hex(char *s, int l, char *d)
{
    while(l--)
    {
        char* p = s+l;
        char* p2 = p-1;
        *(d+l/2) =
        ( (*p>'9'? *p+9 : *p) & 0x0f ) |
        ( (*p2>'9'? *p2+9 : *p2) << 4 );
        l--;
    }
}

int main () {
    char s[]= "6F6B6f6b";
    char d[5];
    d[4] = '
#include 
void from_hex(char *s, int l, char *d)
{
while(l--)
{
char* p = s+l;
char* p2 = p-1;
*(d+l/2) =
( (*p>'9'? *p+9 : *p) & 0x0f ) |
( (*p2>'9'? *p2+9 : *p2) << 4 );
l--;
}
}
int main () {
char s[]= "6F6B6f6b";
char d[5];
d[4] = '\0';
from_hex(s,8,d);
printf("%s",d);
return 0;
}
'; from_hex(s,8,d); printf("%s",d); return 0; }

Output results:okok

EOF

The original text was first published at: https://www.chenxublog.com/2020/03/08/c-fast-convert-hex-char-array.html

If you have a better way, please leave a message below