暗号に関する本を読むと、たいていは「シーザー暗号 - Wikipedia」が紹介されている。
鍵そのものと暗号化アルゴリズムを分けて考えるという現代的な(?)性質は満たしているが、容易に解読できるので実用性がない、という位置づけで。
簡単なので簡単にプログラムが作れる。Emacsの *scratch*バッファでやってみるのも簡単。
仕様
- 与えられた文字列を暗号化する。
- 文字列はアスキー文字のみ。
- 小文字は大文字に変換する。
- A-Z以外の文字(スペースやピリオドなど)はそのまま。
- 鍵(下の例で言うと仮引数の key)の値は正でも負でもいい。
- 鍵の値が0や26、-26なら変化なし。
コード
3つの関数に分けた。
;; 入力の正規化のようなことを行ってから暗号化。すなわち、 ;; 文字列を大文字に変換し、鍵を 0 から 25 までの値に変換する。 (defun my-caesar (str key) (my-caesar-string (upcase str) ((lambda (n) (while (< n 0) (incf n 26)) (mod n 26)) key) )) ;; 文字列を暗号化する (defun my-caesar-string (str key) (if (< (length str) 1) "" (concat (my-caesar-string1 (substring str 0 1) key) (my-caesar-string (substring str 1) key)))) ;; 文字を暗号化する(厳密には「文字」ではなく、文字列長が1の文字列) (defun my-caesar-string1 (c key) (if (string-match "[a-zA-Z]" c) (char-to-string (+ ?A (mod (+ key (- (string-to-char c) ?A)) 26))) c))
関係ないが、組み込み関数の名前が長くてつらい(string-to-char
やsubstring
など)。
テスト
- その1. アトム
-
(my-caesar "foo bar baz!" 27) => "GPP CBS CBA!"
- その2. リスト
-
(mapcar (lambda (str) (my-caesar str -1)) '("foo bar baz!" "hoge fuga piyo.")) => ("ENN AZQ AZY!" "GNFD ETFZ OHXN.")
0 件のコメント:
コメントを投稿