Rotate by 13 (ROT13)λ︎
ROT13 is one of the simplest ciphers which uses an alphabet as a circle of characters, swapping each character with a character 13 positions later in the alphabet, assuming 26 character of an English alphabet.
A dictionary can be generated to translate between the original alphabet and the rotated alphabet, providing a simple way to generate an encrypted message.
Create a projectλ︎
Use Clojure CLI tools and clj-new to create a new Clojure project.
Define an alphabetλ︎
Define an alphabet to use as a basis for conversion. Take the string of all characters and convert to a sequence of character types.
Generate a cypherλ︎
To convert a character, first build up a cypher. A cypher in this case is simply a hash-map that creates a dictionary lookup defining what each character should be changed to.
cycle creates a lazy sequence of the alphabet that continually cycles. This provides an 'infinite' sequence from which we will take only the characters needed.
The dictionary is composed of the original alphabet and a new alphabet that is offset by 13 characters, half the number of characters in the dictionary.
(drop 13 (cycle alphabet)) will drop the first 13 characters. As
cycle creates an 'infinite' alphabet, there are still plenty of characters to make a second alphabet.
(take 26 (drop 13 (cycle alphabet))) will get a new alphabet of 26 characters, starting from the 14th character,
zipmap is used to join two collections together to form a hash-map, e.g. the lookup dictionary. In this case the original alphabet and the new alphabet.
(zipmap alphabet (take 26 (drop 13 (cycle alphabet))))
This expression is nested and can be harder to parse by those new to Clojure. The code can be written using a threading marco, that demonstrated the flow of data transformation.
Using the thread last macro,
->>, the result of each expression becomes the last argument for the next expression.
Using the clojure.core/replace function with the cypher hash-map and a string of text returns a converted string of text.
Define a functionλ︎
rot13 function with the algorithm created. The function takes the alphabet and the text to be encrypted. Passing both pieces of data as arguments ensures that the function is pure, i.e. free from side effects.
(defn rot13 [alphabet text] (let [cipher (->> (cycle alphabet) (drop 13) (take 26) (zipmap alphabet))] (apply str (replace cipher text))))
Call the rot13 function with the
english-alphabet and a sentence as a string.
An encrypted copy of the sentence is returned.
clojure.string library is more idiomatic approach when working with string types.
apply str was used to join a sequence of characters into a string.
clojure.string/join combines a sequence of characters into a string.
clojure.string namespace to use the functions contained within. Add the require to the namespace definition of
rot13 function to use
clojure.string/join rather than
(defn rot13 [alphabet text] (let [cipher (->> (cycle alphabet) (drop 13) (take 26) (zipmap alphabet))] (string/join (replace cipher text))))