现在的位置: 首页 > 综合 > 正文

A Tool to Convert Binary to Text File and Convert Back

2019年03月11日 ⁄ 综合 ⁄ 共 2256字 ⁄ 字号 评论关闭

Thus, I write a tool to convert any binary file to hex-printable text file and then convert back.

There're some differences between unix and windows while programming the tool. I encountered two differences. 

First one. I decide to use ifstream and ofstream STL classes to achieve this. In unix, even though I do not specify "ios:binary" while creating ifstream/ofstream object, it works well. But in windows, I have to specify "ios:binary", otherwise, problems encountered,
e.g. ifstream returns EOF(End of File) prematurely, output file is larger than expected(because "\n" is translated to "\r\n"), etc. 

Second one, a minor one. There's strcasecmp function in unix, but there's not in windows. The counterpart of strcasecmp in windows is stricmp. 

Notes. In unix, "split" can be used to divide a large file to small ones, "xxd" can be used to dump a binary file to hex-printable characters,  "cat" can be used to do the reverse thing. In windows, "type" is the counterpart of "cat". 

#include <stdio.h> 
#include <ctype.h> 
#include <string.h>
#include <assert.h>
#include <iosfwd>
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

char hex2num(char c);
short hexNumFromChar(char* c2);
void error_exit(char* err) ;
void usage_exit(char**) ;
char dic[]="0123456789ABCDEF";

int main(int argc, char* argv[]){
    if(argc!=4) {
        usage_exit(argv);
    }
    bool isEncode = false;
    if (stricmp(argv[1],"encode")==0){
        isEncode = true;
    } else if(stricmp(argv[1],"decode")==0) {
        isEncode = false;
    } else {
        usage_exit(argv);
    }

    ifstream ifile(argv[2],ios::binary);
    ofstream ofile(argv[3],ios::binary);
    if(!ifile || !ofile){
        error_exit("check infile and outfile");
    }

    char c;
	short s;
    char hi,lo;
    char buf[2];
	//int total=0;
    if(isEncode) {
        while(ifile.read(&c,1)){
			//cout << ++total << endl; 
            hi = (((unsigned char)c & 0xf0) >> 4);
            lo = ((unsigned char)c & 0x0f);
            ofile.put(dic[hi]);
            ofile.put(dic[lo]);
        }
    } else {
        while(true) {
            if(!ifile.read(&c,1)) break;
            buf[0]=c;
            if(!ifile.read(&c,1)) error_exit("the file have odd number of chars");
            buf[1]=c;
            s=hexNumFromChar(buf);
            //c=((buf[0]<<4) | (buf[1]&0xf));
            ofile.put((char)s);
        }
    }
	ofile.flush();
    ifile.close();
    ofile.close();
    return 0;
}

void error_exit(char* err) {
    cerr<<err<<endl;
    exit(1);
}

void usage_exit(char** argv) {
    cout << "Usage:" << argv[0] << " <encode/decode> <infile> <outfile>" << endl;
    exit(2);
}

short hexNumFromChar(char* c2){
    char n1,n2;
    n1=hex2num(c2[0]);
    n2=hex2num(c2[1]);
    return n1*16+n2;
}

char hex2num(char c){
   if (isdigit(c)) return c-'0';
   if (isalpha(c)) {
    if(islower(c)) c=toupper(c);
    return 10+c-'A';
   }
   assert(0);
   return -1;
}

抱歉!评论已关闭.