思い出した!この日ちゃんと生きてたよ!!!
ぼくは今、暗号系のお話を読んでいる。たぶん分かる人には分かるんだけども、暗号のノンフィクションみたいなやつです。上下巻わかれてるやつ。まだ半分くらい、しかも上巻の半分くらいしか読んでないけども。
それでですね、その上巻の半分くらい読んだ中の1/4くらいで、レイルフェンス暗号とか出てきた。なんかクソ簡単ぽいので、とりあえずエンコードするヤツつくってた。本に載ってるのはわりかし簡単なレイルフェンス暗号で、秘密鍵はたぶんフェンス数だと思うのですが、じつはもうちょっと複雑で、何文字を一緒にするかというのも秘密鍵にできるぽい(ref:暗号化アルゴリズム(1):19世紀より前の暗号)。
sub encode_rail_fence { my ($plain, $fence, $length) = @_; $plain =~ s/\W+//g; my (@words, $cipher); my @chars = split //, $plain; push @words, join '', splice @chars, 0, $length while (@chars); my $cipher; for my $fence_no ( 0 .. $fence - 1 ) { $cipher .= join '', @words[ grep { $_ % $fence == $fence_no } 0 .. @words ]; } $cipher; }
これ使うと、
my $plain = 'THY SECRET IS THY PRISONER; IF THOU LET IT GO, THOU ART A PRISONER TO IT';
とかいう文字列が、
print encode_rail_fence( $plain, 2, 1 ), "\n";
とかすると、
TYERTSHPIOEITOLTTOHURARSNROTHSCEITYRSNRFHUEIGTOATPIOETI
みたく暗号化される。$lengthが1だと簡単に復号できるのだけども、$length > 1が秘密鍵になるとわりかしプログラムが複雑になってきて、めんどくて復号用関数つくるのやめた。てか眠かったのです。
シーザー暗号はもっと簡単。とか言って即興で作ったので、じつはちがうかもわからない。愛嬌愛嬌。
sub encode_caeser { my ($plain, $offset) = @_; $plain =~ s/\W+//g; my @alpha = ('a' .. 'z'); my %map; @map{@alpha} = @alpha[ $offset .. $#alpha, 0 .. $offset - 1]; return join '', map { uc $map{ lc( $_ ) } } split //, $plain; } sub decode_caeser { my ($cipher, $offset) = @_; my @alpha = ('A' .. 'Z'); my %map; @map{@alpha} = @alpha[ -$offset .. -1, 0 .. $#alpha - $offset - 1 ]; return join '', map { lc $map{ $_ } } split //, $cipher; }
そういうわけで、ぼくはちゃんと生きてたし、この日を無駄にしたわけじゃないよ、というお話でした。