(def DEFAULT_ALPHABET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") (def DEFAULT_SEPS "cfhistuCFHISTU") (def DEFAULT_SALT "") (def DEFAULT_MIN_LENGTH 0) (def MIN_ALPHABET_LENGTH 16) (def SEP_DIV (/ 7 2)) (def GUARD_DIV 12) (def DEFAULTS {:salt DEFAULT_SALT :min-length DEFAULT_MIN_LENGTH :alphabet DEFAULT_ALPHABET :seps DEFAULT_SEPS}) (defn- map-indexed [f xs] (map f xs (range 0 (length xs)))) (defn- int-hash [num i] (mod num (+ 100 i))) (defn- as-indexed [x] (if (indexed? x) x [x])) (defn- swap [arr i j] (def a (in arr j)) (def b (in arr i)) (put arr i a) (put arr j b) ) (defn- difference [s1 s2] (seq [x :in s1 :when (not (find |(= x $) s2))] x)) (defn- intersection [s1 s2] (seq [x :in s1 y :in s2 :when (= x y)] x)) (defn consistent-shuffle [alphabet salt] (if (= "" salt) alphabet (let [alph-bytes (apply array (string/bytes alphabet)) salt-bytes (string/bytes salt) max-index (- (length alph-bytes) 1)] (var p 0) (loop [i :down [max-index 0]] (let [v (mod (- max-index i) (length salt-bytes)) n (get salt-bytes v) j (mod (+ n v (set p (+ p n))) i)] (swap alph-bytes i j))) (apply string/from-bytes alph-bytes)))) (defn setup [opts] (let [{:salt salt :alphabet alphabet :seps seps :min-length min-length} (merge DEFAULTS opts) alph-bytes (string/bytes alphabet) salt-bytes (string/bytes salt) seps-bytes (string/bytes seps) unbalanced-alph (difference alph-bytes seps-bytes) unbalanced-seps (intersection alph-bytes seps-bytes) ] (pp unbalanced-seps) { :seps (apply string/from-bytes unbalanced-seps) :alph (apply string/from-bytes unbalanced-alph) :salt salt :min-length min-length })) (defn encode "Convert nums to hashids encoded form" [source & opts] (let [config (setup (table ;opts)) nums (as-indexed source) hash-int (reduce + 0 (map-indexed int-hash nums))] (pp config) "j0gW"))