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);
}
試しにprintfで値を吐かせてみると、"1"と表示された。なので、上のコードは次の様に変換される。
void main(void) {
printf(&1["\021%six\012\0"],
(1)["have"]+"fun"-0x60);
}
つまり、(1)["have"]というのは"have"[1]と等価であるのだ。この時点でのソースコードは次のようになる。
void main(void) {
printf(&1["\021%six\012\0"],
'a'+"fun"-0x60);
}
これは"un"という文字列である。
void main(void) {
printf(&1["\021%six\012\0"],
"un");
}
ここで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 ]