RosettaCodeData/Task/Vigen-re-cipher/Clojure/vigen-re-cipher-1.clj

30 lines
963 B
Clojure

(ns org.rosettacode.clojure.vigenere
(:require [clojure.string :as string]))
; convert letter to offset from \A
(defn to-num [char] (- (int char) (int \A)))
; convert number to letter, treating it as modulo 26 offset from \A
(defn from-num [num] (char (+ (mod num 26) (int \A))))
; Convert a string to a sequence of just the letters as uppercase chars
(defn to-normalized-seq [str]
(map #'first (re-seq #"[A-Z]" (string/upper-case str))))
; add (op=+) or subtract (op=-) the numerical value of the key letter from the
; text letter.
(defn crypt1 [op text key]
(from-num (apply op (list (to-num text) (to-num key)))))
(defn crypt [op text key]
(let [xcrypt1 (partial #'crypt1 op)]
(apply #'str
(map xcrypt1 (to-normalized-seq text)
(cycle (to-normalized-seq key))))))
; encipher a text
(defn encrypt [plaintext key] (crypt #'+ plaintext key))
; decipher a text
(defn decrypt [ciphertext key] (crypt #'- ciphertext key))