2012-03-30 4 views
1

"custom" ord関数とchr関数を記述する必要があります。私はシーザー暗号をメッセージに適用するための小さなプログラムを書いています。これを行う最速の方法は何ですか?カスタムord関数とchr関数

関数 "ord"は、文字を取り、適切な数値を返すだけでよい。 'A'は0を返し、Bは1を返すなどとします。大文字のみを使用すると仮定すると、26通りの可能性があります。私はむしろ26人の警備員を書いてはいけません。これを行うより良い方法はありますか?使用方法は次のとおりです。 "chr"関数はその逆を行う必要があります。

caesarencipher::Int->Int->String->String 
caesarencipher r s p = map chr . map encipher $ plaintext 
    where 
     plaintext = map ord p 
     encipher p = mod (r*p + s) 26 

caesardecipher::Int->Int->String->String 
caesardecipher r s c = map chr . map decipher $ ciphertext 
    where 
     ciphertext = map ord c 
     inverser x | mod (r * x) 26 == 1 = x 
        | otherwise = inverser (x + 1) 
     decipher c = mod ((inverser 1) * (c - s)) 26 

答えて

2

これらの機能のカスタムバージョンを最も迅速に定義するには、可能なすべてのパターンを書き出します。複数の句をセミコロンで区切って行にパックすることができます。

しかし、私はあなたが得るものを見ません。 ordchrはすべて遅いではありません。すべてのコードポイントを処理するからです。 Charはすでに完全なUnicodeコードポイントを格納しています。実際には、ordは基本的に無料で、chr(有効性の単純なチェックを超えて)にする必要があります。では、標準ordchr関数に適切な数値オフセットを適用するだけではどうですか? (私はエラーチェック完全に省略しないであろう上記提案されているようにもちょうどパターンを書き出すことに注意してください。GHCが例外をスローします値は、あなたの条項のどれもが扱えるないことが渡された場合。)

+0

問題があることです標準的なord関数とchr関数は私の目的のためには機能しません。 Unicodeは私が使用している暗号化アルゴリズムを壊します。 –

+0

ああ。あなたのコメントをもっと慎重に読む必要がありました。次に、オフセットが何であるか把握する必要があります。 –

+0

'ord' A '≡65です。具体的には、 'ordAZ x = ord x - 65'と' chrAZ x = chr(x + 65) 'です。 – ehird

1
isAZ x = x >= 'A' && x <= 'Z' 

ordAZ c | isAZ c = x where x = ord x - ord 'A' 
chrAZ x | isAZ c = c where c = chr $ x + ord 'A'