ENIGMA on ruby
映画「imitation game」を見たので、enigmaを作ってみた。
もともと、チューリングやenigmaに興味があったので、それなりに映画を楽しめたが、予備知識のない場合はどうなのだろう。短い時間に様々な要素を説明せねばならず、暗号の中身については大いに端折っていたのは仕方がないことではあるが、私ごとき者には多少残念。 チューリング級の天才であれば、「天気予報のような定型文を解読のターゲットに使えば良い」ということはさっさと思いついてしまいそうな気がする。もちろん実話通りではないのは当然としても、ちょっと紋切りかと。 カンバーバッチは品格ある変人を演じさせれば天下一品。非常にらしかったと思う。(私はチューリングの人格について知るところはほとんどない)。
さて、例によってインチキプログラムである。それらしくコード化され、デコードもされるが、正しいかどうかはまったくわからないてふもの。オブジェクトを作ってみてなかなか楽しかった。再代入を使わずにこれを書けるとは思えない。という感想を抱いた。
#!/usr/bin/ruby
class Roter
def initialize ( str )
@pattern_a = str
@pattern_b = "abcdefghijklmnopqrstuvwxyz"
p ""
p "initialize ==="
p @pattern_a
p @pattern_b
end
def rotate ( )
str = @pattern_a
@pattern_a = str[1,str.length-1] + str[0,1]
p ""
p "rotate ==="
p @pattern_a
p @pattern_b
end
def shift ( org_str, direction )
if direction==1 then
new_str = org_str.tr( @pattern_a, @pattern_b )
elsif direction==-1 then
new_str = org_str.tr( @pattern_b, @pattern_a )
end
p "shift === "
print "#{@pattern_a} => #{@pattern_b}\n"
print "shift:#{org_str} => #{new_str}\n"
return new_str
end
end
# system initialize
roter = []
roter0 = "abcdefghijklmnopqrstuvwxyz"
roter1 = "abcdefghijklmnopqrstuvwxyz"
roter2 = "abcdefghijklmnopqrstuvwxyz"
roter[0] = Roter::new( roter0 )
roter[1] = Roter::new( roter1 )
roter[2] = Roter::new( roter2 )
org_str = ARGV[0]
new_str = ""
c = 0
n = 0
org_str.split(//).each{ | c |
(0..2).each{ |i|
c = roter[i].shift( c, 1 )
}
c = c.tr( roter2, roter2.reverse )
[2,1,0].each{ |i|
c = roter[i].shift( c, -1 )
}
new_str = new_str + c
n = n + 1
roter[0].rotate( )
if n % roter0.length == 0 then
roter[1].rotate( )
end
if n % (roter0.length * roter1.length ) == 0 then
roter[2].rotate( )
end
}
p org_str
p new_str
Comments