適合MCU用的C語言快速互轉HEX(16進制)和原始字符串/數組方法


原文發布於:https://www.chenxublog.com/2020/03/08/c-fast-convert-hex-char-array.html

博客園僅供存檔,如果有優化余地,也不會進行后續更正

緣由

這個起因是昨晚群里有人在討論怎么把字符串轉成HEX方法最佳,討論到最后變成哪種方法效率最優了。畢竟這代碼是要在MCU上面跑的,要同時考慮到時間和空間的最優解。

當然討論的是有結果的,具體實現的方法和代碼在下面展示。

char數組轉16進制HEX串

例子:

將如下的量

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

轉成

"313233343500"
"0102030405FF"

這樣的結果

這個其實很簡單,追求速度的話,查表就好了

0-16對應0-F即可:

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];
    }
}

完整測試代碼如下:

#include <stdio.h>
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;
}

輸出結果:31323334

16進制HEX串轉成數值數組

例子:

將類似"AAbb2fFF"的量轉成{0xAA,0xBB,0x2F,0xff}這樣的結果

這里如果還用查表的話,這個rom占用會浪費掉不少空間,所有查表法直接就被否決掉了(如果是PC上,追求極致速度的話,當然可以用)。

同時,為了通用性,代碼需要兼容大小寫兩種輸入數據

在仔細研究數據的結構時,我發現了個規律:

ASCII中的0-9對應了0x30-0x39
ASCII中的A-F對應了0x41-0x46
ASCII中的a-f對應了0x61-0x66

也就是說,只要這一個字符大於0x39,那它一定是字母;同時,在上面的分析也可以發現,如果這個字符是字母,不論大寫小寫,只需要看低四位就可以直接判斷這個字符代表的數是多少

具體邏輯如下:

判斷這個字符是否大於0x39

如果不是,直接取這個字符的低四位當作結果

如果是,則為字母,將他的低四位加上9即為所需結果

具體實現代碼也如下:

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--;
    }
}

完整的測試代碼:

#include <stdio.h>

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;
}

輸出結果:okok

EOF

原文先發布於:https://www.chenxublog.com/2020/03/08/c-fast-convert-hex-char-array.html

如果你有更好的方法,歡迎在原文下面留言討論😁


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM