C言語: IOCCC 1987 "unix"

Kazuki Ohta, 2005/12/30



エキスパートCプログラミングに以下の様なソースコードが掲載されていた。これは1987年にIOCCC (International Obfuscated C Code Competition)において優勝を飾ったDavid Kornのソースコードである。一目見ただけでは結果が分からなかったので、解析してみようと思う。
void main(void) {printf(&unix["\021%six\012\0"], (unix)["have"]+"fun"-0x60);}
まずはインデントを変えてみる。
void main(void) {
  printf(&unix["\021%six\012\0"],
         (unix)["have"]+"fun"-0x60);
}
unixというidentifierが使われているが、これは明らかに外部で宣言されたものである。
試しにprintfで値を吐かせてみると、"1"と表示された。なので、上のコードは次の様に変換される。
void main(void) {
  printf(&1["\021%six\012\0"],
         (1)["have"]+"fun"-0x60);
}
次に気になるのは、(1)["have"]という表現だ。これは気づくのに時間がかかったが、str[idx] = *(str + idx) = idx[str]とも書ける性質を利用している。
つまり、(1)["have"]というのは"have"[1]と等価であるのだ。この時点でのソースコードは次のようになる。
void main(void) {
  printf(&1["\021%six\012\0"],
         'a'+"fun"-0x60);
}
'a'の値は97, 0x60は十進数で表すと96。つまり第二引数は"fun"+1という形へと還元できる。
これは"un"という文字列である。
void main(void) {
  printf(&1["\021%six\012\0"],
         "un");
}
(1)["have"]で見た様に、&1["\021%six\012\0"]というのも&("\021%six\012\0"[1])と書ける。
ここでman printfを紐解いて見ると、"\NNN character with octal value NNN (1 to 3 digits)"なる記述が有る。つまりAsciiで言うと"\021"はDevice Control 1, "\12"はLine Feedを表す1文字のCharacterとなる。なので元のコードは結局"%six\012\0"という文字列と同値で有る。
ここでLF + '\0'は'\n'と等しい事から、結局は次の様なコードとなる事が分かる。
void main(void) {
  printf("%six\n",
         "un");
}

これでめでたく"unix"と表示される仕組みが解明出来た。

[ return ]