第21回IOCCC入賞作品「踊る人形」

2012-10-18

第21回IOCCCで銀賞を頂きました。とても光栄です。

http://www.ioccc.org/2012/whowon.html

自分で書いたコードですが、もう既に理解できなくなってく来ているので早うちに解説を残しておきます。

作品のテーマは最も難解な部類に入るファイルフォーマットであるPDFと、あえて難解に書いたC言語のコラボレーションです。

このプログラムはテキスト文字列を入力として受け取り、難読化したPDFファイルを出力します。 この難読化手法は、有名な推理小説「踊る人形」に登場する単一換字式暗号です。

たとえば、

% gcc -o hamano hamano.c
% echo 'Hello World!' | ./hamano > hello.pdf

と実行すると以下の様なPDFを出力します。

出力PDF

このPDFファイルは、Adobe Acrobat Readerやevince, XpdfなどのPDFリーダーで読むことができます。さらにこのPDFファイルはCコンパイラでコンパイルすることができます。 得られた実行ファイルは、難読化前の文字列を復元します。

% gcc -o hello -xc hello.pdf
% ./hello
Hello World!

任意のグリフを表現できるPDFならではの作品ですね。もちろんこのグリフは一般的なフォントとしては存在しないので、PDFに埋め込む必要があります。

これらの字型はType3フォントと呼ばれるフォーマットでつくりました。 Type3フォントはPostScript言語で表現できるコンパクトなフォント仕様なのですが、 現代ではほとんど使われておらず、何処を探してもこのType3フォントを利用しているPDFファイルを見つける事は出来ませんでした。 PDF仕様について興味ある方は仕様書を読んでみてください。1300ページほどあります。

難しかったかったのは、どうやってこのフォントデータをプログラムに押し込めるかという事でした。 いくらType3フォントが小さいといっても、まともに埋め込むと10kbyte以上のサイズを要します。これでは大会ルールのサイズ制限(2024byte)に収まりません。

そこで、グリフを頭と胴体、右腕、左腕、右足、左足、逆立ちフラグという様に分解することで、データ表現を可能な限り圧縮し、実行時に完全なフォントを生成しています。

たしかこんなレイアウトで分割した各部位への参照を保持しています。

逆立フラグ左腕右腕右足左足
1bit2bit2bit2bit2bit

これが配列v[32]実態です。

実は元ネタの小説の中では「f」,「j」,「k」,「q」,「u」,「w」,「x」,「z」といった文字は登場しませんのでこれらの字型は記述量が少なくなるように私が勝手に創作しました。またスペースについても独自の解釈を加え大文字の場合に旗を付け加えています。 逆立ちした場合、足で旗を持っているように見えるのは改善の余地がありますね。

ちなみに頂いた賞の名前「Most elementary use of C」はホームズの映画やドラマでおなじみのセリフ「Elementary, My Dear Watson.」(初歩的なことだよワトソン君)から来ていると思われます。