ネコミミ言語をデコードしてみた
1レス内に全命令のリファレンスが入る素敵な言語。
http://alfalfalfa.com/archives/01159.html
のHello World!が基地外じみててワラタ。
さっそく師匠を捕まえて「お前が作者だろう」とひとしきりいじった後、これってほんとにHello Worldなのか気になった。
"H"とかどっから引っ張ってきてるの?
真面目に読んでみる。
前の方のアドレスをカウンタにしてASCIIコードを上手いこと作ってるみたいだけど、これは手デコードがメンドイなぁ。
インタプリタを書くほどやる気もないので、Cで相当のコードを書いてみた。
#include <stdio.h> #define ONIISAMA ((*p)++) #define WATASHINOSHIMOBE ((*p)--) #define NEKOMIMI (p++) #define NEKOMIMIMODE (p--) #define YAKUSOKUYO (printf("%c",*p)) #define KISSKISS while(*p != 0){ #define KISSSHITAKUNATTYATTA } int main(int argc,char *argv[]) { char data[128] = {0}; char *p = data; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; KISSKISS NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; KISSKISS NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; NEKOMIMI; ONIISAMA; ONIISAMA; NEKOMIMIMODE; NEKOMIMIMODE; NEKOMIMIMODE; WATASHINOSHIMOBE; KISSSHITAKUNATTYATTA NEKOMIMI; ONIISAMA; ONIISAMA; NEKOMIMI; ONIISAMA; NEKOMIMIMODE; NEKOMIMIMODE; NEKOMIMIMODE; WATASHINOSHIMOBE; KISSSHITAKUNATTYATTA NEKOMIMI; NEKOMIMI; YAKUSOKUYO; NEKOMIMI; ONIISAMA; YAKUSOKUYO; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; YAKUSOKUYO; YAKUSOKUYO; ONIISAMA; ONIISAMA; ONIISAMA; YAKUSOKUYO; NEKOMIMI; YAKUSOKUYO; NEKOMIMIMODE; NEKOMIMIMODE; WATASHINOSHIMOBE; NEKOMIMIMODE; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; KISSKISS NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA; NEKOMIMIMODE; WATASHINOSHIMOBE; KISSSHITAKUNATTYATTA NEKOMIMI; YAKUSOKUYO; NEKOMIMI; YAKUSOKUYO; ONIISAMA; ONIISAMA; ONIISAMA; YAKUSOKUYO; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; YAKUSOKUYO; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE; YAKUSOKUYO; NEKOMIMI; ONIISAMA; YAKUSOKUYO; return 0; }
キス系の命令の説明が煩雑だが、結局はwhile(*p != 0)だと悟った。
実行してみる。
akari:/tmp# gcc a.c akari:/tmp# ./a.out Hello World!akari:/tmp#
おお・・・。
ロジック的には正しいことは分かったけど、どういうロジックかは分からん。
もうちょいC言語っぽくしてみた。
#include <stdio.h> #define COUNTER_1 0 #define COUNTER_2 1 #define MOJI_UPPER 2 #define MOJI_LOWER 3 #define MOJI_SYMBOL 4 int main(int argc,char *argv[]) { char data[128] = {0}; char *p = data; for(p[COUNTER_1] = 4;p[COUNTER_1] > 0;p[COUNTER_1]--) { for(p[COUNTER_2] = 4;p[COUNTER_2] > 0;p[COUNTER_2]--) { p[MOJI_UPPER] += 4; p[MOJI_LOWER] += 6; p[MOJI_SYMBOL] += 2; } p[MOJI_UPPER] += 2; p[MOJI_LOWER]++; } printf("%c",p[MOJI_UPPER]); /* H */ p[MOJI_LOWER]++; printf("%c",p[MOJI_LOWER]); /* e */ p[MOJI_LOWER] += 7; printf("%c",p[MOJI_LOWER]); /* l */ printf("%c",p[MOJI_LOWER]); /* l */ p[MOJI_LOWER] += 3; printf("%c",p[MOJI_LOWER]); /* o */ printf("%c",p[MOJI_SYMBOL]); /* */ p[MOJI_UPPER]--; for(p[COUNTER_2] = 4;p[COUNTER_2] > 0;p[COUNTER_2]--) { p[MOJI_UPPER] += 4; } printf("%c",p[MOJI_UPPER]); /* W */ printf("%c",p[MOJI_LOWER]); /* o */ p[MOJI_LOWER] += 3; printf("%c",p[MOJI_LOWER]); /* r */ p[MOJI_LOWER] -= 6; printf("%c",p[MOJI_LOWER]); /* l */ p[MOJI_LOWER] -= 8; printf("%c",p[MOJI_LOWER]); /* d */ p[MOJI_SYMBOL]++; printf("%c",p[MOJI_SYMBOL]); /* ! */ return 0; }
うむ、ネコミミ言語の超少ないオペコードからすると最適解なのかも知れないけれど、高級言語的に見ると結構な辻褄合わせが入ってますな。
師匠とは「これでテキストファイルを暗号化したら面白くね?」とか言う話で終わった。