« 脳年齢 | 自己複製プログラム(Perl) | ここしばらくの予定 »

Fri April 14,2006

自己複製プログラム(Perl)

さて少し前のエントリで書いていた自己複製コードです。結局Cは大変なので、Perlで書いてしまいました。簡単にやろうとすると

#!/usr/bin/perl

srand(time|$$);
$copyfile=int(rand(1000));
open(FILE, __FILE__);
open(OUT, ">${copyfile}");
while(<FILE>){
print OUT;
}

close(FILE);
close(OUT);

chmod(0777,$copyfile);

これで出来てしまうんですけど、自分を開いて参照するのは全然面白くないので、自分自身を参照しない方法で実装してみました。

完成コードはこんな感じ

#!/usr/bin/perl
$cmd='$q=pack("C",39);$seed=sprintf("%05d",int(rand(99999)));$salt=sprintf("%02d",int(rand(99)));$copyfile=crypt($seed,$salt);open(out, ">${copyfile}");print out "#!/usr/bin/perl\n";print out "\$cmd=$q$cmd$q;\n";print out "eval(\$cmd);\n";close(out);chmod(0777,$copyfile);';
eval($cmd);

$cmdの部分は意図的に改行を入れてません。
ちょっとしたポイントは最初の$q=pach("C",39);でシングルクオートを$qに代入している部分。
これが無いとprint out "\$cmd=$q$cmd$q;\n";の部分で困ったことになります。
\'で表現すると2世代目以降のうまくいきません。

書いておいてなんですが、単純な複製コードはいまいち面白くないですね。
つぎは自分を暗号化しつつ複製をつくるコードを紹介します。
こっちはもう少し面白いと思います
ここを読んでいる人で面白いと思う人がいるかどうかは謎ですが(^^;

Posted at 00:45

Trackback Pings

このエントリーのトラックバックURL:
http://pam-ya.com/cgi/mt/mt-tb.cgi/1379

Comment

 自己複製プログラム、以前にCの実装を見た覚えがあります。「ハッカーズ大辞典」だったと記憶しており、先ほどからページをめくって探しているのですが...まだ見つけられません。恐ろしく簡潔なコードで、でも上手く動くことを理解するのに時間がかかった気がします...ああもどかしい。運良く見つけられたらまた。

Posted by 陰郎 at 01:57 04.14

このコードではファイルネームのランダム生成とかやってるので若干複雑になってるんですけど、Cでやるとバイナリを弄る必要があるのでこれ以上には簡潔にはならないはずです。
#本当はCの方が面白くて、もうアイディアもあるんですが
#デバッガでメモリ上に展開されたコードを取り出したり、
#リターンポインタを弄って無理矢理特定のメモリ領域を関数として呼び出す
#手法を使ったりする必要があるので、時間的に無理でした(TT

おそらく陰郎さんがおっしゃってるのは
"自分のソースコードを表示するプログラム"
だと思います
#これはこれでおもしろいんですけどね

この手のプログラムは一般的にQuineと呼ばれていてググってみると色々見つかります
たとえばCでは
main(p){printf(p,34,p="main(a){printf(p,34,p=%c%s%c,34); }",34); }
てな感じのがあります

Posted by EIJ at 10:57 04.14

あ、それです。クワインですね。「ハッカーズ大辞典」にもその見出し語で載ってました。ちなみに載ってたのは以下のようなのでした。EIJ さんの書かれたのと似てますね。

char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}

オブジェクトモジュールのレベルでの自己複製はチト思いつきません...

Posted by 陰郎 at 12:43 04.14

オブジェクトモジュールの自己複製はマニアックなテクニックがてんこ盛りになるのでかなり面白いはずです
またそのうちコンセプトレベルで解説してみます

Posted by EIJ at 22:45 04.14