Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Created June 28, 2021 16:32
Show Gist options
  • Save ericnormand/4bca050e029545069d0e84b827fc8123 to your computer and use it in GitHub Desktop.
Save ericnormand/4bca050e029545069d0e84b827fc8123 to your computer and use it in GitHub Desktop.
432 PurelyFunctional.tv Newsletter

Atbash Cipher

The Atbash Cipher is simple: replace every letter with its "mirror" in the alphabet. A is replaced by Z. B is replaced by Y. Etc. Write a function to calculate it.

Examples

(atbash "") ;=> ""
(atbash "hello") ;=> "svool"
(atbash "Clojure") ;=> "Xolqfiv"
(atbash "Yo!") ;=> "Bl!"

Please maintain capitalization and non-alphabetic characters.

Thanks to this site for the problem idea, where it is rated Very Hard in Python. The problem has been modified.

Please submit your solutions as comments on this gist.

To subscribe: https://purelyfunctional.tv/newsletter/

@stuartstein777
Copy link

stuartstein777 commented Jun 28, 2021

(defn atbash [s]
 (let [alphabet "abcdefghijklmnopqrstuvwxyz"
       alphabet-uc (str/upper-case alphabet)
       cipher (merge (zipmap alphabet (reverse alphabet))
                     (zipmap alphabet-uc (reverse alphabet-uc)))]
   (->> (map (fn [c] (cipher c c)) s)
        (apply str))))

@steffan-westcott
Copy link

(require '[clojure.string :as str])

(let [alpha "abcdefghijklmnopqrstuvwxyz"
      cipher (apply merge (map #(zipmap % (str/reverse %)) [alpha (str/upper-case alpha)]))]
  (defn atbash [s]
    (str/escape s cipher)))

@mchampine
Copy link

mchampine commented Jun 29, 2021

(defn atbash [s]
  (let [f (fn [b v] [(char (+ b v)) (char (- (+ b 25) v))])
        mf (fn [ff b] (map #(f b %) (range 26)))
        mm (into {} (concat (mf f (int \a)) (mf f (int \A))))]
    (clojure.string/escape s mm)))

@ZaymonFC
Copy link

(defn atbash [s]
  (let [a-z (map char (range (int \a) (inc (int \z))))
        A-Z (map char (range (int \A) (inc (int \Z))))
        alphabet-keys (concat a-z A-Z)
        alphabet-values (reverse (concat A-Z a-z))
        atbash-mapping (zipmap alphabet-keys alphabet-values)]
    (->> s (map (fn [x] (get atbash-mapping x x))) (apply str)))

@grierson
Copy link

grierson commented Jun 29, 2021

(def alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
(def uppercaseAlphabet (seq alphabet))
(def lowercaseAlphabet (map #(Character/toLowerCase %) alphabet))
(def dictionary
  (merge
    (zipmap uppercaseAlphabet (reverse uppercaseAlphabet))
    (zipmap lowercaseAlphabet (reverse lowercaseAlphabet))))


(defn atbash [s]
  (if (empty? s)
    ""
    (apply str (map #(get dictionary % %) s))))

@jaihindhreddy
Copy link

jaihindhreddy commented Jun 29, 2021

(require '[clojure.string :as str])

(let [a (int \a), z (int \z), A (int \A), Z (int \Z)
      flip #(let [i (int %)]
             (cond (<= a i z) (char (- z (- i a)))
                   (<= A i Z) (char (- Z (- i A)))
                   :else %))]
  (defn atbash [s]
    (str/escape s flip)))

@sztamas
Copy link

sztamas commented Jun 30, 2021

(defn char-range [from to]
  (map char (range (int from) (inc (int to)))))

(defn mirror-char [char-range]
  (zipmap char-range (reverse char-range)))

(def lowercase-letters (char-range \a \z))

(def uppercase-letters (char-range \A \Z))

(def mirror-letters (merge (mirror-char lowercase-letters) (mirror-char uppercase-letters)))

(defn atbash [s]
  (->> s (map #(get mirror-letters % %)) (apply str)))

@vpetruchok
Copy link

(def en-alphabet "abcdefghijklmnopqrstuvwxyz")

(defn atbash-mk-translation-table [alphabet]
  (->> alphabet
       (map-indexed (fn [i el]
                      [el (nth alphabet (- (dec (count alphabet)) i))]))
       (into {})))

(def translation-table
  (merge (atbash-mk-translation-table en-alphabet)
         (atbash-mk-translation-table (clojure.string/upper-case en-alphabet))))

(defn encode [ch]
  (get translation-table ch ch))

(defn atbash [s]
  (if (empty? s)
    ""
    (->> s
         (map encode)
         (clojure.string/join))))

@KubqoA
Copy link

KubqoA commented Jul 1, 2021

(defn char-range [from to] (map char (range (int from) (+ (int to) 1))))
(defn mirror-part [xs] (zipmap xs (reverse xs)))
(def mirror (merge (mirror-part (char-range \A \Z)) (mirror-part (char-range \a \z))))

(defn atbash [s] (apply str (replace mirror s)))

@alex-gerdom
Copy link

alex-gerdom commented Jul 1, 2021

(defn atbash [s]
   (let [A-Z (map char (range 65  91))
         a-z (map char (range 97 123))
         conversions (merge (zipmap A-Z (reverse A-Z))
                            (zipmap a-z (reverse a-z)))]
     (->> s
          (map #(get conversions % %))
          (clojure.string/join ""))))
  • Edited for off by one error for ascii code point of Z.

@KingCode
Copy link

KingCode commented Oct 7, 2021

(def mirror (let [lks "abcdefghijklmnopqrstuvwxyz", 
                  uks (clojure.string/upper-case lks)
                  lvs (reverse lks), 
                  uvs (reverse uks)]
              (-> (zipmap lks lvs)
                  (merge (zipmap uks uvs)))))

(defn atbash [msg]
  (->> msg
       (map #(get mirror % %))
       (apply str)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment