You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.1 KiB

(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 [alph-bytes seps-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 alph-unbal
(consistent-shuffle seps-unbal salt-bytes))]
{
: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"))