(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 balance [sep-bytes alph-bytes] [ ] ) (defn consistent-shuffle [alph-bytes salt-bytes] (if (empty? salt-bytes) alph-bytes (let [alph-array (apply array alph-bytes) max-index (- (length alph-array) 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-array i j))) alph-array))) (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) alph-unbal (difference alph-bytes seps-bytes) seps-unbal (intersection alph-bytes seps-bytes) [seps-bal alph-bal] (balance (consistent-shuffle seps-unbal salt-bytes) alph-unbal)] { :seps (apply string/from-bytes seps-unbal) :alph (apply string/from-bytes alph-unbal) :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"))