シーザー暗号をブルートフォースアタックしてみる

暗号技術入門を買ったのでちょっとずつ読んでます。

暗号技術入門 第3版

暗号技術入門 第3版

第二章で シーザー暗号をブルートフォースアタックするクイズがあったので
common lisp で やってみた記録です

(defun shift-string (str shift)
    (map
        'string 
        #'(lambda (c)
            (code-char
                (+
                    (mod (- (char-int c) (char-int #\A) shift) 26)
                    (char-int #\A))))
        str))

(defun caesar-attack (str)
    (dotimes (i 26)
        (format
            t
            "~A, ~A~%"
            i (shift-string str i))))

こんな感じで使います

? (caesar-attack "ABCDEFG")
0, ABCDEFG
1, ZABCDEF
2, YZABCDE
3, XYZABCD
4, WXYZABC
5, VWXYZAB
6, UVWXYZA
7, TUVWXYZ
8, STUVWXY
9, RSTUVWX
10, QRSTUVW
11, PQRSTUV
12, OPQRSTU
13, NOPQRST
14, MNOPQRS
15, LMNOPQR
16, KLMNOPQ
17, JKLMNOP
18, IJKLMNO
19, HIJKLMN
20, GHIJKLM
21, FGHIJKL
22, EFGHIJK
23, DEFGHIJ
24, CDEFGHI
25, BCDEFGH
NIL

もうちょっとキレイに書けるようになりたいなぁ。。。

追記

ちょっときれいにしてみたつもり

(defun shift-string (str shift)
  (let ((s (string-upcase str)))
   (map
        'string
        #'(lambda (c)
            (let ((c-idx (- (char-int c) (char-int #\A))))
              (code-char
                (+
                    (mod (- c-idx shift) 26)
                    (char-int #\A)))))
        s)))

(defun caesar-attack (str)
    (dotimes (i 26)
        (format
            t
            "~A, ~A~%"
            i (shift-string str i))))

roswell を使用した実行方法もメモ

$ ros run --load caesar-attack.lisp -e '(caesar-attack "abcde")' -q