シーザー暗号とも呼ばれる回転暗号を実装してみましょう。
シーザー暗号は、0から26までの整数の鍵を使って、アルファベットのすべての文字をずらす、単純なシフト暗号です。
鍵に0または26を使うと、剰余演算により、常に同じ結果になります。
文字は、鍵の値と同じ数だけずれます。
回転暗号の一般的な表記はROT + <key>です。
最もよく使われる回転暗号はROT13です。
ROT13をラテンアルファベットに適用すると、次のようになります。
Plain: abcdefghijklmnopqrstuvwxyz
Cipher: nopqrstuvwxyzabcdefghijklm
回転暗号は、鍵の候補が27通りあり、そのうち使えるのが25通りなので、アトバシュ暗号よりも強力です。
暗号文は、スペースや句読点も含めて、入力と同じ書式で書き出されます。
omgをtrlにしますcをcにしますCoolをCoolにしますThe quick brown fox jumps over the lazy dog.をGur dhvpx oebja sbk whzcf bire gur ynml qbt.にしますGur dhvpx oebja sbk whzcf bire gur ynml qbt.をThe quick brown fox jumps over the lazy dog.にしますrotate関数を実装する必要があります。この関数はIntとStringを受け取り、回転暗号でエンコードします。
型について迷ったときは、用意されたシグネチャを使ってもかまいません。ただし、それに縛られて創造性を制限しないようにしましょう。
この演習ではテキストデータを扱います。歴史的な理由により、HaskellのString型は文字のリスト[Char]と同じ意味です。テキストデータをより効率的に扱うには、Text型を使うこともできます。
この演習の発展として、任意で次のこともできます。
import qualified Data.Text as T
import Data.Text (Text)
Text型を使います(例:rotate :: Int -> Text -> Text)。Data.Textのコンビネータは、たとえばT.packのように呼び出します。Data.Textのドキュメントを調べます。StringをすべてTextに置き換えます。つまり、次のとおりです。rotate :: Int -> Text -> Text
この部分は完全に任意です。