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

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

1 问题描述

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

#include 
#include 
#include 

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 
#include 
#include 

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的输出问题分析)