查看: 688|回复: 0

[经验] 怎么把字符串转成HEX方法

[复制链接]
  • TA的每日心情
    无聊
    2018-11-16 10:48
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2020-7-30 14:18:43 | 显示全部楼层 |阅读模式
    分享到:
    缘由
    这个起因是昨晚群里有人在讨论怎么把字符串转成HEX方法最佳,讨论到最后变成哪种方法效率最优了。毕竟这代码是要在MCU上面跑的,要同时考虑到时间和空间的最优解。
    当然讨论的是有结果的,具体实现的方法和代码在下面展示。
    char数组转16进制HEX串
    例子:
    将如下的量
    char str[ = "12345";char data[ = {1,2,3,4,5,0xff};[size=0.8em]C
    COPY


    转成
    "313233343500""0102030405FF"[size=0.8em]C
    COPY


    这样的结果
    这个其实很简单,追求速度的话,查表就好了
    从0-16对应0-F即可:
    const char hex_table[ = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};[size=0.8em]C
    COPY


    然后一个个从表里取出来,拼到对应位置即可:
    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;    }}[size=0.8em]C
    COPY


    完整测试代码如下:
    #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;}[size=0.8em]C
    COPY


    输出结果: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--;    }}[size=0.8em]C
    COPY


    完整的测试代码:
    #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;}[size=0.8em]C
    COPY


    输出结果:okok
    EOF
    如果你有更好的方法,欢迎在下面留言讨论
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-29 02:40 , Processed in 0.106611 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.