I was looking through Hal's blog when I came across his hexer program. I thought that I should write the complimentary program, that is, given an ascii file of hex characters (e.g. "01CAFEBABE") it will write actual bytes to stdout.
chris@papaya:c$ cc helloworld.c chris@papaya:c$ ./a.out Hello World! chris@papaya:c$ cat a.out | ./hexer | ./dehexer > helloworld chris@papaya:c$ chmod a+x helloworld chris@papaya:c$ ./helloworld Hello World!
It seems to work (I changed the name to 'helloworld' because doing
cat a.out | ./hexer | ./dehexer > a.outseems to clobber the file in a bad way. Without further ado:
/* dehexer - Convert an ascii file of hex characters into the corresponding binary file. Any non-hex characters are silently skipped (newlines, tabs, etc.) Copyright 2008 Christopher Wilson, based in part on hexer by Hal Canary (also DTPD) Dedicated to the Public Domain */ /* cc -o dehexer dehexer.c */ #include#include int main (int argc, char *argv[]) { char x; int char_out = 0; int low = 0; // LSBs, 1 for true while (fread(&x, sizeof(x), 1, stdin) == 1) { if (x > 47 && x < 58) { // digit is 0-9 x = x - 48; handle_byte(x, &char_out, low); } else if (x > 64 && x < 71) { // digit is A-F x = x - 55; handle_byte(x, &char_out, low); } else if (x > 96 && x < 103) { // digit a-f x = x - 87; handle_byte(x, &char_out, low); } else { // skip anything that isn't 0-9A-Z, or a-z continue; } low = (low + 1) % 2; // flip the high/low bit marker } return(0); } /* handle_byte - if low is true then it prints the full byte. If low is false, set char_out to 16 times x. */ int handle_byte(int x, char *char_out, int low) { if(low) { *char_out += x; putc(*char_out, stdout); } else { *char_out = x * 16; } return 0; } /* EOF */
No comments:
Post a Comment