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.
janet-nanoid/nanoid.janet

42 lines
1.2 KiB

(def- DEFAULT_ALPHABET "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
(def- DEFAULT_RNG (math/rng (os/time)))
(def- masks [15 31 63 127 255])
(defn gen
"Generate secure random ID. Default size of 21."
[&keys {:size size
:alphabet alphabet}]
(default size 21)
(default alphabet DEFAULT_ALPHABET)
(let [mask (find |(>= $ (dec (length alphabet))) masks)
step (->> alphabet
(length)
(/ (* 1.6 mask size))
(math/ceil))
result (array/new size)]
(while (> size (length result))
(loop [byte :in (os/cryptorand step)
:when (> size (length result))]
(let [mask-byte (band mask byte)
char (get alphabet mask-byte)]
(if char (array/push result char)))))
(string/from-bytes ;result)))
(defn gen-non-secure
"Generate pseudorandom ID. Default size of 21."
[&keys {:size size
:alphabet alphabet
:rng rng}]
(default size 21)
(default alphabet DEFAULT_ALPHABET)
(default rng DEFAULT_RNG)
(string/from-bytes
;(seq [i :range [0 size]]
(get alphabet (math/rng-int rng (length alphabet))))))