Obfuscated C
I had written a little C program a while back for the 19th annual International Obfuscated C Coding contest.
Not only did my code not win … it didn’t even warrant an entry in the honorable mentions or anything like that. If you look at the winners and look back at my code, you’ll immediately see why; the winners and the runners-up were much more creative than my effort.
Rather than get lost in obscurity, I felt that my entry needed to be published, so it has been given the honor of appearing in my first public blog post.
Everyone, please meet lawless.c … a ROT-13 encoder/decoder that encodes/decodes one line at a time:
// Copyright (c) 2009 by Jim Lawless
#include <stdio.h>
#include <ctype.h>
char *z="DCFEBA";
int zzz;
void zzzzzzzzz(void) { zzz=zzz; }
typedef void (*ZZ)(void);
#define I
void zzzzzzz(void) { z-=6; }
#define r(x) isalpha(x) ? tolower(x)>'m' ? x-'\r' : x+'\r' : x
void zzzzzz(void) { if(!(zzz-10)) { z++; z++; } }
#define o(x) Z[*z-'A']();
#define t(x)
void zzzz(void) { zzz=fgetc(stdin); }
#define a(x) for(;*z;z++)
void zzzzz(void) { zzz=r(zzz); }
#define s(x)
void zzzzzzzz(void) { fputc(zzz,stdout); }
ZZ Z[12]={ zzzzzzz, zzzzzzzz, zzzz, zzzzzzzzz, zzzzzz, zzzzz };
int main() {
I s(lit) t(he) s(heet) t(he) s(heet) I s(lit) a(nd)
o(n) t(he) s(litted) s(heet) I s(it)
}
The rules for the 19th annual competition had noted that C preprocessor tricks might just as well not be used as each entry would be run through the preprocessor for expansion.
Here’s what the above code would look like after preprocessing:
char *z="DCFEBA";
int zzz;
void zzzzzzzzz(void) { zzz=zzz; }
typedef void (*ZZ)(void);
void zzzzzzz(void) { z-=6; }
void zzzzzz(void) { if(!(zzz-10)) { z++; z++; } }
void zzzz(void) { zzz=fgetc((&_iob[0])); }
void zzzzz(void) { zzz=(__mb_cur_max > 1 ? _isctype(zzz,(0x0100|0x1|0x2)) : _pctype[zzz] &amp; (0x0100|0x1|0x2)) ? tolower(zzz)>'m' ? zzz-'\r' : zzz+'\r' : zzz; }
void zzzzzzzz(void) { fputc(zzz,(&_iob[1])); }
ZZ Z[12]={ zzzzzzz, zzzzzzzz, zzzz, zzzzzzzzz, zzzzzz, zzzzz };
int main() {
for(;*z;z++)
Z[*z-'A']();
}
I tried to use preprocessor abuse to get my cutesy “I slit the sheet…” lines into view … but the core of the processing was done via indirect invocation of entries in an array of function-pointers.