這個原由是昨晚羣裏有人在討論怎麼把字符串轉成HEX
方法最佳,討論到最後變成哪一種方法效率最優了。畢竟這代碼是要在MCU上面跑的,要同時考慮到時間和空間的最優解。html
固然討論的是有結果的,具體實現的方法和代碼在下面展現。數組
例子:測試
將以下的量code
char str[] = "12345"; char data[] = {1,2,3,4,5,0xff};
轉成htm
"313233343500" "0102030405FF"
這樣的結果blog
這個其實很簡單,追求速度的話,查表就行了字符串
從0-16
對應0-F
便可:get
const char hex_table[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
而後一個個從表裏取出來,拼到對應位置便可:io
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]; } }
完整測試代碼以下:table
#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
例子:
將相似"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
原文先發佈於:https://www.chenxublog.com/2020/03/08/c-fast-convert-hex-char-array.html
若是你有更好的方法,歡迎在原文下面留言討論😁