C语言快速互转HEX(16进制)和原始字符串/数组
C語言快速互轉HEX(16進制)和原始字符串/數組
緣由
這個起因是昨晚群里有人在討論怎么把字符串轉成HEX方法最佳,討論到最后變成哪種方法效率最優了。畢竟這代碼是要在MCU上面跑的,要同時考慮到時間和空間的最優解。
當然討論的是有結果的,具體實現的方法和代碼在下面展示。
char數組轉16進制HEX串
例子:
將如下的量
char str[]="12345";char data[]={1,2,3,4,5,0xff};12C
Copy
轉成
"313233343500""0102030405FF"12C
Copy
這樣的結果
這個其實很簡單,追求速度的話,查表就好了
從0-16對應0-F即可:
constchar hex_table[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};123C
Copy
然后一個個從表里取出來,拼到對應位置即可:
voidto_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];}}12345678C
Copy
完整測試代碼如下:
#include<stdio.h>constchar hex_table[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};voidto_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);return0;}1234567891011121314151617181920C
Copy
輸出結果:31323334
****** 帶分隔符的字符串轉Hex數組*****
const char hex_table[] = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
//返回實際長度,空間不足返回-1
int to_hex(char *src, int len, char* seg, int slen, char *dst, int dlen)
{
int size = 2*len+(len-1)*slen;
if(dlen < size) {
return -1;
}
while(len--)
{
*(dst+2*len+1+len*slen) = hex_table[(*(src+len))&0x0f];
*(dst+2*len+len*slen) = hex_table[(*(src+len))>>4];
for(int ii=0; ii < slen; ii++) {
*(dst+2*len+(len-1)*slen+ii) = *(seg+ii);
}
}
return size;
}
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即為所需結果
具體實現代碼也如下:
voidfrom_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--;}}123456789101112C
Copy
完整的測試代碼:
#include<stdio.h>1void 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;
}
C
Copy
輸出結果:okok
EOF
如果你有更好的方法,歡迎在下面留言討論😁
更新
2020.3.9:Antecer帶來了更高效的hex轉數組代碼
#include<stdio.h>1void from_hex(char s, int l, char d)
{
while(l–)
{
d = (s>‘9’ ? s+9 : s) << 4;
++s;
d |= (s>‘9’ ? s+9 : s) & 0x0F;
++s;
++d;
}
}
int main () {
char s[]= “6F6B6f6b”;
char d[5];
d[4] = ‘\0’;
from_hex(s,4,d);
printf("%s",d);
return 0;
}
C
Copy
因為傳入的指針是臨時變量,所以數組轉hex也可以按此思路稍微優化下:
#include<stdio.h>constchar hex_table[]={‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’};voidto_hex(chars,int l,chard){while(l–){d = hex_table[s >>4]; d++;d = hex_table[s &0x0f]; s++; d++;}}int main (){char s[]=“1234”;char d[9]; d[8]=‘\0’;to_hex(s,4,d);printf("%s",d);return0;}1234567891011121314151617181920212223C
Copy
2020.3.10:稀飯放姜發現內嵌“++”操作比單獨寫一行運行要快
hex轉數組:
#include<stdio.h>1void from_hex(char s, int l, char d)
{
while(l–)
{
(d++) = ( (s>‘9’ ? (s++)+9 : (s++)) << 4 )
| ( (s>‘9’ ? (s++)+9 : *(s++)) & 0x0F );
}
}
int main () {
char s[]= “6F6B6f6b”;
char d[5];
d[4] = ‘\0’;
from_hex(s,4,d);
printf("%s",d);
return 0;
}
C
Copy
數組轉hex:
#include<stdio.h>constchar hex_table[]={‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’};voidto_hex(chars,int l,chard){while(l–){(d++)= hex_table[s >>4];(d++)= hex_table[(s++)&0x0f];}}int main (){char s[]=“1234”;char d[9]; d[8]=‘\0’;to_hex(s,4,d);printf("%s",d);return0;}1234567891011121314151617181920C
Copy
總結
以上是生活随笔為你收集整理的C语言快速互转HEX(16进制)和原始字符串/数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序毕业设计 基于微信小程序在线电
- 下一篇: 【办公常用软件】万彩办公大师教程丨PDF