做通讯项目的时候,经常要进行数据收发校验。发送端的数据通过复杂的通讯系统(例如OFDM系统),依次进行交织、编码(LDPC)、映射、IFFT、串并转换……等等,达到接收端,我们只有通过反复的对比才能验证流程的正确性。因为数据的收发都是比特流,所以经常使用16或者二进制文件进行比较。
很多调试工具都支持数据导出,由于某些原因他们支持的导出格式各不相同。例如:code composer studio支持比较全面,但是NIOS II IDE数据格式只支持16进制导出,quarutus ii等支持也各不相同。例如我们有下面两个文件需要对比:
1,源文件
0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A0102030405060708090A
这个文件是一个16进制文件,其实质是0x01 0x02 0x03 ......这样的十六进制数据。
2,目标文件
01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A 01 02 03 04 05 06 07 08 09 0A
目标文件可能是包含空格,包含0x前缀,例如0x01020304 0x05060708 ....这样的数据。那么怎么对他们进行比较能。下面有个C脚本文件可以实现,功能包含16进制比较和二进制比较。
#include <stdio.h> #include <stdlib.h> #include <string.h> long filesize(FILE *stream) { long curpos, length; curpos = ftell(stream); fseek(stream, 0L, SEEK_END); length = ftell(stream); fseek(stream, curpos, SEEK_SET); return length; } int main(int argc, char **argv){ FILE *fp_input; FILE *fp_output; unsigned long flength = 0L; char *str_file = NULL; unsigned long i = 0L; unsigned long out_size = 0L; char byte_data = 0; char binary_mode = 0; char byte_temp = 0; char hex_byte = 0x00; int j = 0; /* check usage*/ if (argc < 3) { fprintf(stderr, "hex_export version-1.0 2014-06-27 fangying7@zju.edu.cn to use this tool: hex :%s [input hex filename] [output hex file name] ", argv[0]); fprintf(stderr, "binary:%s [input hex filename] [output hex file name] -b ", argv[0]); exit(-1); } if(argc == 4){ binary_mode = 1; printf("convert hex into binary "); } /*open the specified file*/ if((fp_input = fopen(argv[1],"r")) == NULL){ printf("Can't open intput file: %s ",argv[1]); } if((fp_output = fopen(argv[2],"w")) == NULL){ printf("Can't open output file: %s ",argv[2]); } /*get file size*/ flength = filesize(fp_input); if((str_file = (char *)malloc(flength)) == NULL){ fprintf(stderr,"Can't allocate memory for file input! "); exit(-1); } /*read file*/ if(fread(str_file, 1, flength, fp_input) == 0){ fprintf(stderr,"Can't read file! "); exit(-1); } /* do extract hex */ for(i=0; i<flength; i++){ if(*(str_file+i) == '0' && (toupper(*(str_file+i+1)) == 'X')){ /* just omit*/ }else if(isxdigit(*(str_file+i))){ byte_data = toupper(*(str_file+i)); if(byte_data >= '0' && byte_data <= '9'){ hex_byte = byte_data - 0x30; }else{ hex_byte = byte_data - 'A' + 10; } //byte_data = *(str_file+i); if(binary_mode){ for(j=0; j<4; j++){ byte_temp = (hex_byte&(0x1<<(3-j)))>>(3-j); byte_temp += '0'; fprintf(fp_output,"%c ",byte_temp); } out_size++; }else{ fprintf(fp_output,"%c ",byte_data); out_size++; } } } free(str_file); fclose(fp_input); fclose(fp_output); /*message*/ printf("Input file is : %s size = %ld ", argv[1],flength); printf("Output file is : %s size = %ld ",argv[2],out_size); return 0; }
3,使用方式
如果以16进制比较,例如把上面的程序编译为:hex_cmp
hex_cmp src_input.dat src_output.dat :默认进行16进制比较,将文件转换为4bit单位的列模式,而后用 beyond compare等工具比较十分方便。
如果要比较二进制文件,使用方法:
hex_cmp src_input.dat src_output.dat -b:转换为二进制比特流列文件,而后用 beyond compare等工具比较十分方便。