Compare commits

...

2 Commits

Author SHA1 Message Date
34a365960a varint back to int 2025-11-14 12:00:34 +01:00
a52070dfa6 delete incorrect verification 2025-11-14 09:16:55 +01:00
2 changed files with 113 additions and 38 deletions

View File

@@ -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]
)
)

View File

@@ -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))))
)
)