Compare commits
2 Commits
76510be028
...
34a365960a
| Author | SHA1 | Date | |
|---|---|---|---|
| 34a365960a | |||
| a52070dfa6 |
@@ -17,6 +17,25 @@
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defn to-fancy-bin
|
||||
"Return a string with bits from number in a fancy manner"
|
||||
[x]
|
||||
(s/join " "
|
||||
(map s/join
|
||||
(partition 8 (b2/encode (byte-array (map #(b/to-byte %) x)))))))
|
||||
|
||||
|
||||
(defn to-fancy-hex
|
||||
"Return a string with hex values from number in a fancy manner"
|
||||
([x]
|
||||
(to-fancy-hex x 2))
|
||||
([x group-size]
|
||||
(s/join " "
|
||||
(map s/join
|
||||
(partition group-size (hex/encode (byte-array (map #(b/to-byte %) x))))))))
|
||||
|
||||
|
||||
(defn len-bits
|
||||
"How may blocks of n bits are needed to encode this number?
|
||||
|
||||
@@ -31,7 +50,7 @@
|
||||
0 1 ;; One block to zero
|
||||
9223372036854775807 (len-bits (dec x) n) ;; Beware the overflow!! it's best to lose some precision
|
||||
(when (and (>= x 0) (some? n) (> n 0))
|
||||
(int (m/ceil (/ (m/log (inc x)) (m/log (m/pow 2 n))))))))
|
||||
(long (m/ceil (/ (m/log (inc x)) (m/log (m/pow 2 n))))))))
|
||||
|
||||
(comment
|
||||
(len-bits 513 8)
|
||||
@@ -84,44 +103,39 @@
|
||||
([n base]
|
||||
(decimal-to-base n base true))
|
||||
([n base reverse?]
|
||||
(when (and n base)
|
||||
(if (or (nil? n) (nil? base) (zero? n) (zero? base)) ;; Allways [0] for base zero or number zero
|
||||
[0]
|
||||
(loop [acc []
|
||||
x n]
|
||||
(if (zero? x)
|
||||
(vec (if reverse? (reverse acc) acc)) ;; When x is zero, we have finished
|
||||
(recur
|
||||
(conj acc (rem x base)) ;; Accumulate the remainder
|
||||
(quot x base)))))))) ;; Pass the quotient to the next step
|
||||
(if (or (nil? n) (nil? base) (zero? n) (zero? base)) ;; Allways [0] for base zero or number zero
|
||||
[0]
|
||||
(loop [acc []
|
||||
x n]
|
||||
(if (zero? x)
|
||||
(vec (if reverse? (reverse acc) acc)) ;; When x is zero, we have finished
|
||||
(recur
|
||||
(conj acc (rem x base)) ;; Accumulate the remainder
|
||||
(quot x base))))))) ;; Pass the quotient to the next step
|
||||
|
||||
(comment
|
||||
(decimal-to-base 8 2)
|
||||
2r1000
|
||||
)
|
||||
|
||||
|
||||
(defn base-to-decimal
|
||||
"Converts from an array with values in an arbitrary base into decimal values"
|
||||
[n base]
|
||||
(if (or (nil? n) (nil? base) (zero? (count n)))
|
||||
0
|
||||
(int (reduce-kv
|
||||
(long (reduce-kv
|
||||
(fn [acc k v]
|
||||
(+ acc (* v (m/pow base k))))
|
||||
0 (vec (reverse n))))))
|
||||
|
||||
|
||||
(comment
|
||||
(reduce-kv #(+ %1 (* %3 (m/pow 2 %2))) 0 [1 0 0 0])
|
||||
(reduce-kv #(+ %1 (* %3 (m/pow 2 %2))) 0 [1 0 0 0]) ;; backwards!
|
||||
|
||||
(reduce-kv
|
||||
(fn [acc k v]
|
||||
(+ acc (* v (m/pow 2 k))))
|
||||
0 (vec (reverse [1 0 0 0])))
|
||||
|
||||
(base-to-decimal [1 0 0 0] 2)
|
||||
)
|
||||
|
||||
|
||||
(defn int->varint
|
||||
"Converts a integer value to a varint, that is encoded in 7 bits, where the first
|
||||
bit is used to indicate if there are more bytes.
|
||||
@@ -143,44 +157,64 @@
|
||||
(bit-and 2r01111111 (peek b128))))))
|
||||
|
||||
|
||||
(defn to-fancy-bin
|
||||
"Return a string with bits from number in a fancy manner"
|
||||
(defn varint->int
|
||||
"Converts a varint to an integer. Each byte in varint uses the MSB as a continuation
|
||||
bit: if it's value is 1, there are more bites, if it's 0 it's the last block.
|
||||
|
||||
For example, this varint with two bytes:
|
||||
10000001 01111111
|
||||
|
||||
first byte's MSB has value 1, so there is another byte. The second one has a zero
|
||||
in the MSB, so it's the last block. To calculate the final value, you must ignore
|
||||
the MSB and concatenate both bytes:
|
||||
110010110 00000001 -> original value
|
||||
0010110 0000001 -> delete MSB
|
||||
0000001 0010110 -> reverse bytes (little-endian to big endian)
|
||||
00000010010110 -> concatenate
|
||||
00000000 10010110 -> fill the bytes
|
||||
"
|
||||
[x]
|
||||
(s/join " "
|
||||
(map s/join
|
||||
(partition 8 (b2/encode (byte-array (map #(b/to-byte %) x)))))))
|
||||
(base-to-decimal (reverse (map #(bit-and 2r01111111 %) x)) 128))
|
||||
|
||||
(comment
|
||||
;; 150
|
||||
(to-fancy-bin [-106, 1])
|
||||
(to-fancy-bin (map #(bit-and 2r01111111 %) [-106, 1]))
|
||||
(to-fancy-bin (reverse (map #(bit-and 2r01111111 %) [-106, 1])))
|
||||
(varint->int [-106, 1])
|
||||
|
||||
;; Long/MAX_VALUE
|
||||
(to-fancy-bin (map #(bit-and 2r01111111 %) [-1, -1, -1, -1, -1, -1, -1, -1, 128]))
|
||||
(varint->int [-2, -1, -1, -1, -1, -1, -1, -1, 127])
|
||||
)
|
||||
|
||||
(defn to-fancy-hex
|
||||
"Return a string with hex values from number in a fancy manner"
|
||||
([x]
|
||||
(to-fancy-hex x 2))
|
||||
([x group-size]
|
||||
(s/join " "
|
||||
(map s/join
|
||||
(partition group-size (hex/encode (byte-array (map #(b/to-byte %) x))))))))
|
||||
|
||||
|
||||
|
||||
(comment
|
||||
(hex/decode (String/format "%08x" (into-array [1023])))
|
||||
|
||||
(to-fancy-bin [150] )
|
||||
|
||||
(to-fancy-bin [150])
|
||||
|
||||
(to-fancy-bin (int->varint 150))
|
||||
(to-fancy-bin (int->varint 151))
|
||||
|
||||
(to-fancy-hex (int->varint 150))
|
||||
(to-fancy-hex (int->varint 151) 4)
|
||||
|
||||
(varint->int [-106, 1])
|
||||
(varint->int [-105, 1])
|
||||
|
||||
(to-fancy-bin (int->varint Long/MAX_VALUE))
|
||||
(to-fancy-bin (int->varint (dec Long/MAX_VALUE)))
|
||||
|
||||
(to-fancy-hex (int->varint (dec Long/MAX_VALUE)))
|
||||
|
||||
|
||||
(varint->int [-2, -1, -1, -1, -1, -1, -1, -1, 127])
|
||||
|
||||
(to-fancy-bin [2r10010110 2r00000001])
|
||||
|
||||
[2r10010110 2r00000001]
|
||||
[2r0010110 2r0000001]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[alphabase.bytes :as b]
|
||||
[alphabase.base16 :as hex]
|
||||
[alphabase.base64 :as b64]
|
||||
[alphabase.base32 :as b32]))
|
||||
[alphabase.base32 :as b32])
|
||||
(:import (java.util Arrays)))
|
||||
|
||||
|
||||
(deftest len-bits-test
|
||||
@@ -63,6 +64,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftest base-to-decimal-test
|
||||
(testing "Convert from arbitrary base to decimal"
|
||||
(is (zero? (base-to-decimal nil 2)))
|
||||
@@ -75,9 +77,48 @@
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftest decimal-base-decimal-test
|
||||
(testing "Check if convert from decimal to a base and back preserves the original number"
|
||||
(is (= 8 (base-to-decimal (decimal-to-base 8 2) 2)))
|
||||
(is (= 127 (base-to-decimal (decimal-to-base 127 2) 2)))
|
||||
(is (= 417 (base-to-decimal (decimal-to-base 417 13) 13)))
|
||||
))
|
||||
))
|
||||
|
||||
|
||||
|
||||
(deftest int->varint-test
|
||||
(testing "Convert from integer number (int, long, byte, etc) to varint"
|
||||
(is (Arrays/equals (byte-array [0]) (int->varint nil)))
|
||||
(is (Arrays/equals (byte-array [0]) (int->varint 0)))
|
||||
(is (Arrays/equals (byte-array [2r10010110 2r00000001]) (int->varint 150)))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftest int->varint-test
|
||||
(testing "Convert from integer number (int, long, byte, etc) to varint"
|
||||
(is (Arrays/equals (byte-array [0]) (int->varint nil)))
|
||||
(is (Arrays/equals (byte-array [0]) (int->varint 0)))
|
||||
(is (Arrays/equals (byte-array [2r10010110 2r00000001]) (int->varint 150)))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftest varint->int-test
|
||||
(testing "Convert from barint to long"
|
||||
(is (= 0 (varint->int nil)))
|
||||
(is (= 0 (varint->int [0])))
|
||||
(is (= 150 (varint->int [-106, 1])))
|
||||
(is (= 150 (varint->int [22 1])))
|
||||
(is (= 151 (varint->int [-105, 1])))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftest int->varint->int-test
|
||||
(testing "Convert from int to varint and back to int"
|
||||
(is (= 150 (varint->int (int->varint 150))))
|
||||
(is (= 151 (varint->int (int->varint 151))))
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user