ROT13について

投稿者: Anonymous

ROT13という簡単な換字式暗号をRubyで作ってみました。

str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
# ROT13
p str.tr("A-Za-z", "N-ZA-Mn-za-m")
p str.tr("x41-x5ax61-x7a", "x4e-x5ax41-x4dx6e-x7ax61-x6d")

実行結果
“NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm0123456789”
“NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm0123456789”

これを次のようにダブルクォートをシングルクォートにかえると、
下の方の出力が上手くいかないのはなぜでしょうか?
また修正可能であるなら、どのように修正すればよろしいでしょうか?

str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
# ROT13
p str.tr('A-Za-z', 'N-ZA-Mn-za-m')
p str.tr('x41-x5ax61-x7a', 'x4e-x5ax41-x4dx6e-x7ax61-x6d')

解決

シングルクォートの中ではバックスラッシュ記法が使えないため、という文字そのものとして解釈されます。

そうするとString#trは、x4e-x5ax6e-x7ae-の部分をeからまでの範囲として解釈しますが、のコードポイントがeより小さいため、不正な範囲としてエラーになります。

ドキュメントには明確に書かれていませんが、String#trの範囲指定では右辺のコードポイントが左辺のコードポイント以上でなければいけないという制約があるようです。
(a-zはOKだがz-aという逆順の指定はNG)

文字列はダブルクォートまたはシングルクォートで囲まれています。ダブルクォートで囲まれた文字列ではバックスラッシュ記法と式展開(後述)が有効になります。 シングルクォートで囲まれた文字列では、 (バックスラッシュそのもの)と ‘ (シングルクォート) を除いて文字列の中身の解釈は行われません。

http://docs.ruby-lang.org/ja/2.1.0/doc/spec=2fliteral.html#string

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *