IOCCC image by Matt Zucker

The International Obfuscated C Code Contest

2015/burton - Most useful

hex/decimal calculator

Author:

To build:

    make

There is an alternate version which the author discusses in their prog.c vs prog.alt.c section. See Alternate code below.

To use:

    ./prog "expression"

or:

    ./prog

Type in expressions on standard input.

Try:

    ./try.sh

Notice how the script reads in from a file. If you type just:

    ./prog

it will prompt you in the same way. Send ctrl-c to exit.

Finally, if you wish to read the man page:

    man ./calc.1

Alternate code:

An alternate version of this entry, prog.alt.c, is provided. This alternate code is discussed in the “prog.c vs prog.alt.c” section of the author’s remarks below.

Alternate build:

    make alt

Alternate use:

Use prog.alt as you would prog above.

Judges’ remarks:

“Look, Ma, no hands digits!”

The place where some arithmetic operations are done, for example, division or modulo, are easy to find. Where are addition and subtraction?

We were impressed with the level of detail the author “blogged” the obfuscation process.

Author’s remarks:

calc - an integer expression calculator that outputs in both hex and decimal

All useful tools should include sufficient documentation. See the included man page. ;-)

Notes

This program is named calc. Onomatopoeia of sorts, in the visual realm. The formatting was easier: Form Follows Function (although Hou did this better). It was tempting to call it iCalc, with i for integer (and it was written on an iDevice), but sanity prevailed.

Printed in 8 pt Courier, it makes aesthetically pleasing 8.5 x 11 wall art.

prog.c vs prog.alt.c

Dominik Muth observed a syntax error on 1+1, 1-1, 1|1, and 1^1 when using an ARM based computer, although 1*1 and others worked correctly. This occurs because some platforms by default treat char as unsigned char. The original code has this weakness, which can be corrected by adding -fsigned-char to the compile line.

The modified code is agnostic to char signedness.

Why is this entry obfuscated/interesting?

Yes, this is another calculator program.

However, unlike any other calculator source code the author is aware of, this one contains no digits. At all. Anywhere. As in

    grep '[0-9]' prog.c || echo no digits!

Nor are the digits simply obfuscated. There are no character constants. There is only one single, short string, and it does not contain any obfuscated digits. And yet the output is in decimal and hexadecimal, and it accepts octal, decimal, and hex input.

Flow control is by for and return. It is if-less, switch-less, while-less, and hopeless. Literally, if not figuratively. ;-)

The code size is intentionally 2015, as stated by iocccsize -i, and can be reformatted without changes (as in rule2.c source) to exactly 4096 octets.

Finally, calc is interesting, if for no other reason than it is practically useful: Hex/decimal conversion, arithmetic, byte-swapping, bit-shifting, and logical operations with memory, on the command line, or interactively.

But the question is why is the entry obfuscated?

The code follows many industry best-practices:

Compiler warnings

calc is C99 compliant, and is ANSI/C90 compliant except for wanting 64-bit long long. Changing the two long long typedefs to long, and compiling with gcc -m32 yields a program that operates on 32-bit values, with wrap-around of shifts mod 32:

    1<<48
    65536       0x00010000

gcc 4.2.1 without arguments compiles cleanly (e.g. cc prog.c -o prog). This is my workaday compiler. gcc is also clean with -ansi, and -std=c99.

clang 3.6.0 lives up to its namesake, resounding on non-problems. To stifle these complaints:

    -Wno-return-type -Wno-parentheses -Wno-empty-body

When invoked with -ansi -pedantic, there are two warnings, which can be ignored:

With -Wall -std=c99, both are quite noisy, and all can be ignored:

Test Suite:

If the program name begins with an e, it echoes stdin to stdout. This allows for a convenient test suite:

    ln -sf prog eprog
    PATH=. eprog < test.in | diff - test.out

NOTICE to those who wish for a greater challenge:

If you want a greater challenge, don’t read any further: just try to understand the program via the source.

If you get stuck, come back and read below for additional hints and information.

Obfuscation:

If you do not want to puzzle out how it works, see obfuscation.html.

Inventory for 2015/burton

Primary files

Secondary files


Jump to: top