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((&amp;_iob[0])); }
 
void zzzzz(void) { zzz=(__mb_cur_max &gt; 1 ? _isctype(zzz,(0x0100|0x1|0x2)) : _pctype[zzz] &amp;amp; (0x0100|0x1|0x2)) ? tolower(zzz)&gt;'m' ? zzz-'\r' : zzz+'\r' : zzz; }
 
void zzzzzzzz(void) { fputc(zzz,(&amp;_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.