problem 59

Problem 59 - Project Euler

キーと平文との xor を取ることで作成された暗号をブルートフォースで解く問題です。キーは小文字のアルファベット 3 文字を平文の長さだけ繰り返したものです。

(use srfi-1)
(use util.combinations)

(define encrypted (list 79 59 12 ..(省略)...16 15 10 22 73))

; all possible combinations of three lower case characters.
(define key-list
  (let ((ca (char->integer #\a))
        (cz (char->integer #\z)))
    (cartesian-product (make-list 3 (iota (- cz ca -1) ca)))))

;generate infinite encryption key
(define (key-gen key)
  (set! (cdddr key) key)
  key)

(define (p59)
  (fold (lambda (c p) (+ p (char->integer c)))
        0
        (string->list
          (any (lambda (x)
                 (let1 str (apply string (map (lambda (e k)
                                                (integer->char (logxor e k))) ; decrypt
                                              encrypted
                                              (key-gen x)))
                       (if (string-scan str " this ") str #f)))
               key-list))))

(print (p59))

正しく復号できたかどうかは " this " があるかどうかでチェックしていますが、これは後付けです。全てのキーに関して復号した文字列を見てチェックして正しく復号できた文字列には " this " があることを確認してからコードに追加しました。