Skip to content

Instantly share code, notes, and snippets.

@danneu
Last active August 1, 2018 00:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danneu/6755394 to your computer and use it in GitHub Desktop.
Save danneu/6755394 to your computer and use it in GitHub Desktop.
base66 encoder/decoder (encodes integer to url-friendly characters)
(def digits
(seq (str "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
".-_~")))
(def radix (count digits))
(defn encode
"Encodes Long to String."
[n]
(loop [output ""
n n]
(if (>= n radix)
(let [remainder (mod n radix)
char (nth digits remainder)]
(recur (str char output) (quot n radix)))
(str (nth digits n) output))))
(defn decode
"Decodes String to Long."
[s]
(let [idxs (map #(.indexOf digits %) (seq s))]
(->> (reverse idxs)
(map-indexed (fn [power n] (* n (Math/pow radix power))))
(reduce +)
(.longValue))))
(encode 0) ;=> "0"
(encode 65) ;=> "~"
(encode 66) ;=> "10"
Long/MAX_VALUE ;=> 9223372036854775807
(encode Long/MAX_VALUE) ;=> "5w9csrDC~I7"
(decode "0") ;=> 0
(decode "~") ;=> 65
(decode "10") ;=> 66
(decode "5w9csrDC~I7") ;=> 9223372036854775807
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment