Hatena::ブログ(Diary)

まめめも このページをアンテナに追加 RSSフィード

2014-02-19

[] 放射線耐性 Quine (1 文字消しても動く Quine)

放射線はメモリエラーを引き起こすらしいです。そんな放射線が飛び交う過酷な環境でも、できることなら Quine したい。

ということで、プログラム内の 1 文字をランダムに消しても元のプログラムを出力する、なんともロバストな Quine を書きました。*1

何を言っているかわからないと思いますが、こんなふうに動くものです。

# ランダムに 1 文字消すスクリプト
$ cat mutate.rb
src = $<.read
src[rand(src.size), 1] = ""
print src

# rrquine.rb からランダムに 1 文字消したプログラムを生成する
$ ruby mutate.rb rrquine.rb > broken.rb

# 壊れたプログラムを実行する (!)
$ ruby broken.rb > rrquine2.rb

# 元に戻る (!!)
$ diff rrquine.rb rrquine2.rb # 一致!

正直書けるわけないと思ってましたが、なんと書けてしまった。Ruby 恐ろしいなあ。他に書ける言語があるだろうか。*2

以下コード。もっと賢い方法があったら教えてください。

"%\  #{at_exit{eval'(eval q=%(s=%(B%A  C{at_exit{ZGQG##G

}}}ABB.rescue x rescue 42##B

Z=GQG##G

instance_Z=GQG##G

Z Z if Z==instance_Z
).gsub ?Z,%[eval]
7.times{|n|s.gsub! (n+65).chr,(n<1?92:n+33).chr}
puts s.gsub ?Q,%[(eval q=%(]+q+%[))#]
$stdout.flush
exit!0))#'##'

}}}\"".rescue x rescue 42##"

eval='(eval q=%(s=%(B%A  C{at_exit{ZGQG##G

}}}ABB.rescue x rescue 42##B

Z=GQG##G

instance_Z=GQG##G

Z Z if Z==instance_Z
).gsub ?Z,%[eval]
7.times{|n|s.gsub! (n+65).chr,(n<1?92:n+33).chr}
puts s.gsub ?Q,%[(eval q=%(]+q+%[))#]
$stdout.flush
exit!0))#'##'

instance_eval='(eval q=%(s=%(B%A  C{at_exit{ZGQG##G

}}}ABB.rescue x rescue 42##B

Z=GQG##G

instance_Z=GQG##G

Z Z if Z==instance_Z
).gsub ?Z,%[eval]
7.times{|n|s.gsub! (n+65).chr,(n<1?92:n+33).chr}
puts s.gsub ?Q,%[(eval q=%(]+q+%[))#]
$stdout.flush
exit!0))#'##'

eval eval if eval==instance_eval

*1:まあ、実際の放射線によるメモリエラーは除去じゃなくて文字化けですが、さすがにそれは対処不可能だと思う……。

*2:0 バイトで Quine と主張するのはナシで。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/ku-ma-me/20140219/p1