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;
}