Skip to content

Commit

Permalink
Decode function (with generic pipeline)
Browse files Browse the repository at this point in the history
  • Loading branch information
rm-hull committed Jun 20, 2016
1 parent b55c7a4 commit a181cc5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 23 deletions.
43 changes: 29 additions & 14 deletions src/base58/core.clj
Expand Up @@ -24,35 +24,50 @@

(def alphabet (vec "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"))

(defn leading-zeros [s]
(def inverted-alphabet
(into {}
(map #(vector %1 %2)
alphabet
(iterate inc 0))))

(defn count-leading [pred s]
(->>
s
(map byte)
(take-while zero?)
(take-while pred)
count))

(defn string->bigint [s]
(defn string->bigint [base xform s]
(reduce +
(map #(* (byte %1) %2)
(map #(* (xform %1) %2)
(reverse s)
(iterate (partial * 256M) 1M))))
(iterate (partial * base) 1M))))

(def divmod (juxt quot mod))

(defn base-emitter [value]
(def first-char? (partial = (byte (first alphabet))))

(defn emitter [base value]
(if (pos? value)
(let [[d m] (divmod value 58)]
(let [[d m] (divmod value base)]
(cons
(int m)
(lazy-seq (base-emitter d))))))
(lazy-seq (emitter base d))))))

(defn encode [s]
(defn pipeline [from to xform map-fn drop-pred replace-ch s]
(->>
(string->bigint s)
base-emitter
(map alphabet)
s
(string->bigint from xform)
(emitter to)
(map map-fn)
reverse
(concat (repeat (leading-zeros s) (first alphabet)))
(concat (repeat (count-leading drop-pred s) replace-ch))
(apply str)))

;; TODO - decode
(defn encode [value]
(pipeline 256 58 byte alphabet zero? (first alphabet) value))

(defn decode [value]
(->>
(drop-while first-char? value)
(pipeline 58 256 inverted-alphabet char first-char? "\000")))
22 changes: 13 additions & 9 deletions test/base58/core_test.clj
Expand Up @@ -26,21 +26,25 @@
[base58.core :refer :all]))

(deftest check-leading-zeros
(is (= 0 (leading-zeros nil)))
(is (= 0 (leading-zeros "hello world")))
(is (= 0 (leading-zeros "hello\000world")))
(is (= 3 (leading-zeros "\000\000\000hello world"))))
(is (= 0 (count-leading zero? nil)))
(is (= 0 (count-leading zero? "hello world")))
(is (= 0 (count-leading zero? "hello\000world")))
(is (= 3 (count-leading zero? "\000\000\000hello world"))))

(deftest check-string->bigint
(is (= 0 (string->bigint nil)))
(is (= 0 (string->bigint "")))
(is (= 104M (string->bigint "h")))
(is (= (+ 101M (* 256 104)) (string->bigint "he"))))
(is (= 0 (string->bigint 256 byte nil)))
(is (= 0 (string->bigint 256 byte "")))
(is (= 104M (string->bigint 256 byte "h")))
(is (= (+ 101M (* 256 104)) (string->bigint 256 byte "he"))))

(deftest check-encoding
(is (= "" (encode nil)))
(is (= "" (encode "")))
(is (= "StV1DL6CwTryKyV" (encode "hello world")))
(is (= "11StV1DL6CwTryKyV" (encode "\000\000hello world"))))


(deftest check-decoding
(is (= "" (decode nil)))
(is (= "" (decode "")))
(is (= "hello world" (decode "StV1DL6CwTryKyV")))
(is (= "\000\000hello world" (decode "11StV1DL6CwTryKyV"))))

0 comments on commit a181cc5

Please sign in to comment.