美文网首页
C语言关于char类型%02X的输出问题分析

C语言关于char类型%02X的输出问题分析

作者: 冰天 | 来源:发表于2019-07-18 12:08 被阅读0次

    C语言关于char类型%02X的输出问题分析

    1 问题描述

    在与加密机进行交互的时候,原程序从AIX系统迁移到LINUX系统,密码解密一直失败,经过排查发现使用sprintf对bcd码进行asc码的转换,发现转换出来的asc码加密机无法解析,有很多FFFF的情况。
    排查程序发现并未用标准的bcd_to_asc函数,但是这样转换一般情况下没有问题。
    将程序简化代码如下,

    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main()
    {
        char bcd[9];
        char asc[30];
        bcd[0]= 0x8D;
        bcd[1]= 0x2D;
        bcd[2]= 0x3D;
        bcd[3]= 0x4D;
        bcd[4]= 0x5D;
        bcd[5]= 0x6D;
        bcd[6]= 0x7D;
        bcd[7]= 0x8D;
    
        sprintf( asc, "%02X%02X%02X%02X%02X%02X%02X%02X", bcd[0], bcd[1], bcd[2], bcd[3], bcd[4], bcd[5], bcd[6], bcd[7]);
        printf( "%s,%ld\n", asc, strlen(asc));
    
        return 0;
    }
    
    /** 运行结果 **
    FFFFFF8D2D3D4D5D6D7DFFFFFF8D,28
    **/
    

    2 问题分析

    怀疑是%02X输出的有问题,增加日志查看如下:

    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main()
    {
        char bcd[9];
        unsigned char u_bcd[9];
        char asc[30];
        bcd[0]= 0x8D;
        bcd[1]= 0x2D;
        bcd[2]= 0x3D;
        bcd[3]= 0x4D;
        bcd[4]= 0x5D;
        bcd[5]= 0x6D;
        bcd[6]= 0x7D;
        bcd[7]= 0x8D;
    
        strcpy( u_bcd, bcd);
    
        sprintf( asc, "%02X%02X%02X%02X%02X%02X%02X%02X", bcd[0], bcd[1], bcd[2], bcd[3], bcd[4], bcd[5], bcd[6], bcd[7]);
        printf( "%s,%ld\n", asc, strlen(asc));
        sprintf( asc, "%02X%02X%02X%02X%02X%02X%02X%02X", u_bcd[0], u_bcd[1], u_bcd[2], u_bcd[3], u_bcd[4], u_bcd[5], u_bcd[6], u_bcd[7]);
    
        printf( "%s,%ld\n", asc, strlen(asc));
        sprintf( asc, "%d %d %d %d %d %d %d %d", bcd[0], bcd[1], bcd[2], bcd[3], bcd[4], bcd[5], bcd[6], bcd[7]);
        printf( "%s,%ld\n", asc, strlen(asc));
        sprintf( asc, "%d %d %d %d %d %d %d %d", u_bcd[0], u_bcd[1], u_bcd[2], u_bcd[3], u_bcd[4], u_bcd[5], u_bcd[6], u_bcd[7]);
        printf( "%s,%ld\n", asc, strlen(asc));
    
        return 0;
    }
    
    /** 运行结果 **
    FFFFFF8D2D3D4D5D6D7DFFFFFF8D,28
    8D2D3D4D5D6D7D8D,16
    -115 45 61 77 93 109 125 -115,29
    141 45 61 77 93 109 125 141,27
    **/
    

    通过运行结果分析,问题已经很明显了。
    unsigned char是无符号的,char是有符号的,也就是char只有7bit长,0x80开始,已经占用了第8位,这时候char类型会认为已经进行了补码运算,就是负数。
    而%02X的输入情况如下:

    • %X输出,会把后面认为是int,所以当为负数的时候,会进行补码运算,后续进行FFFFFF是对int类型补码的结果.
    • 02只能限定不足2位补齐两位,不能限定只输出2位(实际上只输出两位也是不正确的,会输出FF)

    相关文章

      网友评论

          本文标题:C语言关于char类型%02X的输出问题分析

          本文链接:https://www.haomeiwen.com/subject/iraklctx.html