やりたいこと
伊坂幸太郎の小説「モダンタイムズ」の中で、あるプログラムのコメント中に暗号が仕込んであり、そのコメント文が独自のプログラムの実行コードに変換されるという話がありました。
こんなことできるのかな〜と思って、調べてみるとJavaで似たようなことができるっぽい!
ということで実際に作ってみました。
実際に作ってみた。
↓はJavaのソースです。
(コメントがすごい怪しいですが、気づかないふりをしてください。。)
import java.util.Scanner;
public class ModernTimes {
public static void main(String[] args) {
System.out.print("何か入力してください:");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
// \u000a\u0069\u0066\u0020\u0028\u0069\u006E\u0070\u0075\u0074\u002E\u0065\u0071\u0075\u0061\u006C\u0073\u0028\u0022\u5B89\u85E4\u5546\u4F1A\u0022\u0029\u0029\u0020\u007B
// \u000a\u0069\u006E\u0070\u0075\u0074\u0020\u003D\u0020\u0022\u3042\u306A\u305F\u306F\u76E3\u8996\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u0022\u003B
// \u000a\u007D\u000A
System.out.println("出力結果:" + input);
}
}
このソースを見ると、標準入力から文字列を受け取って、そのまま出力されるはずです。
なので、実際に実行して確認します。
$ java ModernTimes.java
何か入力してください:Hello
出力結果:Hello
予想通り、入力した値がそのまま出力されています。
しかし、安藤商会
と入力してみると、、
安藤商会は実際にモダンタイムズの中で出てきます。
$ java ModernTimes.java
何か入力してください:安藤商会
出力結果:あなたは監視されています。
なんと、、!なぜか、「あなたは監視されています。」と出力されました。。
種明かし
実は、JavaにはUnicodeエスケープという仕組みがあって、コンパイル前に\uXXXという形式をUnicode→テキストに変換しています。
例)\u000aは改行を表します。
この仕組みを利用して、コメント文に文字列をチェックするソースコードを忍ばせておきました。
もうお気づきの方もいると思いますが、実はコメント文をよく見ると
// \u000aXXXXXXX
となっていて、実際には//
のすぐ後で改行がされています。
つまり、コメント文はもう終わっていて、そのあとのUnicodeが実行コードになっていたんです。
エスケープ後のソースコードを見ると↓になっています。
import java.util.Scanner;
public class ModernTimes {
public static void main(String[] args) {
System.out.print("何か入力してください:");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
//
if (input.equals("安藤商会")) {
//
input = "あなたは監視されています。";
//
}
System.out.println("出力結果:" + input);
}
}
しっかり、文字列チェックが入っていることがわかります。
感想
実際に小説に出てくるのは、日本語のコメント文がコンパイルによって実行コードになっているので、今回書いたソースは似て非なるものですが、コメント//
以降は無視されるという先入観があったので、とても勉強になったし感動しました!
参考