暗号に関する本を読むと、たいていは「シーザー暗号 - 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 件のコメント:
コメントを投稿