Jim Hague and his code for the IOCCC
What is this contest based on?
- Obfuscate: tr.v. -cated, -cating, -cates.
- To render obscure. To darken.
- 2. To confuse: his emotions obfuscated his judgement.
[LLat. obfuscare, to darken : ob(intensive) + Lat. fuscare,
to darken < fuscus, dark.] -obfuscation n. obfuscatory adj
The International Obfuscated C Code Contest (abbreviated IOCCC) is a computer programming contest for the most creatively obfuscated C code, whit this rules
- write the most Obfuscated C program within the rules.
- show the importance of programming style, in an ironic way.
- stress C compilers with unusual code.
- illustrate some of the subtleties of the C language.
- provide a safe forum for poor C code.
In the 1986 contest Jim Hague won thanks to this code:
Obviously this code is very very confusing, is the idea, so I am going to explain what it does. What this program does is receive a string of ASCII characters and pass them to the famous morse key. (if you don’t know what morse key is, you can read it here)
But, when we are going to run the program …
It contains many errors but believe it or not, it works!
In order to do this, the program makes use of macros.
What are macros?
In short a macro is a piece of code that is translated into preprocess time
Let’s try to replace the macros manualmente
gcc -E file hague.c
Now it reads better….xd
It makes a little more sense but it is not enough to understand it, let’s improve it and add comments to fully understand what you are doing.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
/* take the array of ASCII values */
char _DAH_[] = "ETIANMSURWDKGOHVFaLaPJBXCYZQb54a3d2f16g7c8a90l?e'b.s;i,d:";/* function main */
main ()
{
char *_DIT, *DAH_, *DIT_, *_DIT_, *malloc (), *gets ();/* in this loop takes the line of input and prints a new line after finish */ for (_DIT = malloc (81), DIT_ = _DIT++; _DIT == gets (_DIT); __DIT ('\n'))/* in nested for loop, check if current character is in _DAH_, if so call conversion; otherwise, print '?' */
for (DAH_ = _DIT;
*DAH_; __DIT (*_DIT_ ? _DAH (*DIT_) : '?'), __DIT (' '), DAH_++) for (*DIT_ = 2, _DIT_ = _DAH_;
*_DIT_ && (*_DIT_ != (*DAH_ >= 'a' ? *DAH_ & 223 : *DAH_));
(*DIT_)++, _DIT_++)
*DIT_ += (*_DIT_ >= 'a' ? *_DIT_ - 'a' : 0);
}/* _DAH - convert to morse code */_DAH (DIT_)
{
__DIT (DIT_ > 3 ? _DAH (DIT_ >> 1) : '\0');
return DIT_ & 1 ? '-' : '.';
}/* __DIT - print to standard output*/__DIT (DIT_)
char DIT_;
{
(void) write (1, &DIT_, 1);
}
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
I’m going to change names to make it easier for you to read the code and fully understand how it works
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Thank you for reading this blog
Facundo Diaz