Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
436 PurelyFunctional.tv Newsletter

XOR Cypher

The XOR Cypher is simple: To encrypt, you do a bitwise XOR of the message with a key. To decrypt it, you XOR it again with the same key.

Write a function encrypt that does an XOR encryption of a message string given a key string. If the message is longer than the key, repeat the key.

Note, I see this as an exercise in JVM byte manipulation.

Thanks to this site for the problem idea, where it is rated Expert in JavaScript. The problem has been modified.

Please submit your solutions as comments on this gist.

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

@steffan-westcott
Copy link

steffan-westcott commented Jul 26, 2021

(defn hex->int [ch]
  (read-string (str "0x" ch)))

(defn hex-chars-xor [x y]
  (format "%x" (bit-xor (hex->int x) (hex->int y))))

(defn encrypt [s key]
  (apply str (map hex-chars-xor s (cycle key))))

@felipereigosa
Copy link

felipereigosa commented Jul 26, 2021

(defn encrypt [message key]
  (let [f (comp #(if (>= % 97) (- % 87) (- % 48)) int)]
    (apply str (map #(format "%x" (bit-xor %1 %2))
                    (map f message)
                    (cycle (map f key))))))

@mchampine
Copy link

mchampine commented Jul 27, 2021

(defn encrypt [clrtxt rawk]
  (let [k (apply str (take (count clrtxt) (cycle rawk)))]
    (map bit-xor (.getBytes clrtxt) (.getBytes k))))

;; and to demonstrate that it works...

(defn decrypt [ciphtxt rawk]
  (let [k (apply str (take (count ciphtxt) (cycle rawk)))]
    (apply str (map char (map bit-xor ciphtxt (.getBytes k))))))

(def ciph (encrypt "you will never guess it" "squeamish ossifrage"))
;; => (10 30 0 69 22 4 5 31 72 78 10 5 22 27 70 21 20 2 22 0 81 28 17)

(decrypt ciph "squeamish ossifrage")
;; => "you will never guess it"

@jonasseglare
Copy link

jonasseglare commented Jul 27, 2021

(->> key
     count
     (mod (count dst))
     (nth key)
     int
     (bit-xor (int c))
     char
     (.append dst)
     (doseq [c message])
     (str dst)
     (let [dst (StringBuilder.)])
     (defn encrypt [message key]))

(encrypt "The angle is Ɵ" "Maître corbeau")
;; => "�\t�T��G�\nR��AǪ"

(encrypt "\t�T��G�\nR��AǪ" "Maître corbeau")
;; => "The angle is Ɵ"

@diavoletto76
Copy link

diavoletto76 commented Jul 27, 2021

(defn encrypt [message key]
  (map bit-xor (map int message) (map int (cycle key))))

(defn decrypt [message key]
  (->> (map bit-xor (map int (cycle key)) (map int message))
       (map char)
       (apply str)))

@miner
Copy link

miner commented Jul 27, 2021

(def ^java.nio.charset.Charset utf8 (java.nio.charset.Charset/forName "UTF-8"))

(defn enc8 [key message]
  (let [utf-bytes (fn [^String s] (.getBytes s utf8))]
    (String. (byte-array (map bit-xor (cycle (utf-bytes key)) (utf-bytes message))))))

@mcuervoe
Copy link

mcuervoe commented Jul 31, 2021

(defn encrypt [key message]
  (->>
    (map vector (seq message) (cycle key))
    (map (fn [[m k]] (bit-xor (int m) (int k))))
    (map (fn [i] (format "%02x" i)))
    (apply str)))

(defn decrypt [key message]
  (let [int-seq (->> message
                     (partition 2)
                     (map (fn [[a b]] (str "0x" a b)))
                     (map read-string))]
    (->> (map vector int-seq (cycle key))
         (map (fn [[m k]] (bit-xor m (int k))))
         (map char)
         (apply str))))

(encrypt "abc" "hello world")
=> "09070f0d0d43160d110d06"
(decrypt "abc" (encrypt "abc" "hello world"))
=> "hello world"

@KingCode
Copy link

KingCode commented Oct 6, 2021

(defn key-bytes [msg key]
  (->> key cycle (take (count msg)) (apply str) 
      (map int)))

(defn encrypt [msg key]
  (let [msg-bytes (->> msg (map int)) 
        key-bytes (key-bytes msg key)]
    (->>  
     (map bit-xor msg-bytes key-bytes)
     (map char)
     (apply str))))

(defn decrypt [encrypted key]
  (encrypt encrypted key))

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