※追記
あとで気づきましたがmixi Engineer's Blogにプログラムの原文が載ってました。
mixi Engineers' Blog » 求人広告バナー用プログラムを書いた話
つまり以下の文章は私の検索能力の乏しさとmixi Engineers' Blogを購読してないことが露呈するだけの内容なので読まなくていいです。。。 とほほ。
ちょっと前からmixiが、TechCrunchとかにエンジニアの求人広告を出しているのですが、何かソースコードが書いてあるんですよね。↓これ
記号プログラミングというのか、わざと難解にしたソースコードですが、C言語のようなので何が出力されるのか気になりました。
んで、ソースコードを地道に写経したんですが、コンパイルできないんですよ。
main(){
char *s = "We make people happy via technology.";
char *_ = "2t\\Grt;snwzs&zn?nvByw1isdy\\";
char m9[*s];
char *O;
while(*_)putchar((
m9[O-O]=*_++,
(++O- --O)[m9]=s[*_++-*s],
('/'-'-')[m9]=s[*_++-*s],
m9[O-O] &(++O- --O))?(++O- --O)[m9]
m9['%'-'#']:
m9['+'-'*']&('$'-'"')[m9]);
}
まあよく見たらわかる通り、11行目と12行目の間に演算子がない。原稿からFlashにする過程で抜け落ちたのかもしれません。
これはもう気になって仕方なくなったので、プログラムを解読することにしました。私はC言語なんて何年も触ってないですが、これは別にライブラリを使ってるわけでもなく、文法さえわかれば何とかなるだろうと思いました。
解読のポイント
そういえばそんな文法だったなーみたいな感じ。初歩的な話なんでしょうか。
- char* OのO(ポインタ)自体は整数が入っている
- ++X - --X は1
- X - X はゼロ
- a[2] と 2[a] と *(a + 2) は等価
解読していく
上のルールに従い、whileの初回ループだけ丁寧に書き直してみるとこんな感じになります。 インクリメント/デクリメントはわかりにくさを増大させるので行を分けて、三項演算子はif文に書き直しました。
m9[0] = '2';
_++; // *_は't'
m9[1] = 'n'; // s['t'-'W'] => s[29]
_++; // *_は'\\'
m9[2] = 'k'; // s['\\'-'W'] => s[5]
_++; // *_は'G'
if (m9[0] & 1 /* 0 */) {
putchar(m9[1] /* 演算子抜け */ m9[2]);
} else {
putchar(m9[1] & m9[2]); // 'n' & 'k' => j
}
最初のループでは「j」が出力されました。この時点で「ああ、どうせ『join mixi』とか表示されるのが期待値なんだろうな」と想像がつきます。
問題は抜けている演算子なんですが、整形されたif文を見ると、ビットAND「&」とビットOR「|」が書かれていれば、コードが対称的になって美しいですよね。
if (m9[0] & 1) {
putchar(m9[1] | m9[2]);
} else {
putchar(m9[1] & m9[2]);
}
判断基準は想像の域を出てないですが、元のソースに「|」を足してやるとコンパイルできるようになり、コンパイル後の実行ファイルは「join mixi」を表示するようになりました。めでたしめでたし。これでぐっすり眠れます。
main(){
char *s = "We make people happy via technology.";
char *_ = "2t\\Grt;snwzs&zn?nvByw1isdy\\";
char m9[*s];
char *O;
while(*_)putchar((
m9[O-O]=*_++,
(++O- --O)[m9]=s[*_++-*s],
('/'-'-')[m9]=s[*_++-*s],
m9[O-O] &(++O- --O))?(++O- --O)[m9]|
m9['%'-'#']:
m9['+'-'*']&('$'-'"')[m9]);
}
あ、ちなみに私はmixiの関係者でもないし、mixiに転職したいわけでもなく、単に釣られただけです。うーん、まさかこれは、面接で「このコードの問題点は?」をいきなり聞くとか、そういう高度な求人広告だったりするんでしょうか。 まあ、ないか、さすがに。