前提
ROT13は、暗号の一種です。
仮に文字列test
を暗号化すると、13個先のアルファベットであるgrfg
に変換されるものです。
ROT13をRubyで実装
最初ソースコードを書いた際は、ROT13の変換パターンをhashでまとめて、文章の頭文字だけが大文字という条件下だったため、下記のコードのように大文字の場合だけcapitalize
を最後当てるようにしてました。
ALPHABET_HASH =
{"a"=>"n",
"b"=>"o",
"c"=>"p",
"d"=>"q",
"e"=>"r",
"f"=>"s",
"g"=>"t",
"h"=>"u",
"i"=>"v",
"j"=>"w",
"k"=>"x",
"l"=>"y",
"m"=>"z",
"n"=>"a",
"o"=>"b",
"p"=>"c",
"q"=>"d",
"r"=>"e",
"s"=>"f",
"t"=>"g",
"u"=>"h",
"v"=>"i",
"w"=>"j",
"x"=>"k",
"y"=>"l",
"z"=>"m"}
def rot13(string)
list = []
strings = string.downcase.split('')
strings.each{|s| ALPHABET_HASH.include?(s) ? list << ALPHABET_HASH[s] : list << s }
string[0] == string.capitalize[0] ? list.join.capitalize : list.join
end
そもそも、hashで定義するパターンに大文字を入れれば良いことに気付いたので、修正後は結構すっきりなソースコードに
ALPHABET_HASH =
{"a"=>"n", "b"=>"o", "c"=>"p", "d"=>"q", "e"=>"r", "f"=>"s", "g"=>"t", "h"=>"u", "i"=>"v", "j"=>"w", "k"=>"x", "l"=>"y", "m"=>"z", "n"=>"a", "o"=>"b", "p"=>"c", "q"=>"d", "r"=>"e", "s"=>"f", "t"=>"g", "u"=>"h", "v"=>"i", "w"=>"j", "x"=>"k", "y"=>"l", "z"=>"m", "A"=>"N", "B"=>"O", "C"=>"P", "D"=>"Q", "E"=>"R", "F"=>"S", "G"=>"T", "H"=>"U", "I"=>"V", "J"=>"W", "K"=>"X", "L"=>"Y", "M"=>"Z", "N"=>"A", "O"=>"B", "P"=>"C", "Q"=>"D", "R"=>"E", "S"=>"F", "T"=>"G", "U"=>"H", "V"=>"I", "W"=>"J", "X"=>"K", "Y"=>"L", "Z"=>"M"}
def rot13(string)
strings = string.split('')
strings.map{|s| ALPHABET_HASH.include?(s) ? ALPHABET_HASH[s] : s }.join
end
納得できるコードを書いた後、色々調べてみたところtr
メソッドを使えばこんなにシンプルにできたのか。。。
string.tr("A-Za-z", "N-ZA-Mn-za-m")
おまけ
定数のhashはこんな感じで作りました。大文字は後から追加したので別途upcase当てました。
('a'..'z').to_a
key = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
value = ["n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"]
ary = [key, value].transpose
h = Hash[*ary.flatten]
ALPHABET_HASH =
{"a"=>"n",
"b"=>"o",
"c"=>"p",
"d"=>"q",
"e"=>"r",
"f"=>"s",
"g"=>"t",
"h"=>"u",
"i"=>"v",
"j"=>"w",
"k"=>"x",
"l"=>"y",
"m"=>"z",
"n"=>"a",
"o"=>"b",
"p"=>"c",
"q"=>"d",
"r"=>"e",
"s"=>"f",
"t"=>"g",
"u"=>"h",
"v"=>"i",
"w"=>"j",
"x"=>"k",
"y"=>"l",
"z"=>"m"}
ALPHABET_HASH.to_h{|k,v| [k.upcase,v.upcase]}