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 (defn len-bits
"How may blocks of n bits are needed to encode this number? "How may blocks of n bits are needed to encode this number?
@@ -31,7 +50,7 @@
0 1 ;; One block to zero 0 1 ;; One block to zero
9223372036854775807 (len-bits (dec x) n) ;; Beware the overflow!! it's best to lose some precision 9223372036854775807 (len-bits (dec x) n) ;; Beware the overflow!! it's best to lose some precision
(when (and (>= x 0) (some? n) (> n 0)) (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 (comment
(len-bits 513 8) (len-bits 513 8)
@@ -84,44 +103,39 @@
([n base] ([n base]
(decimal-to-base n base true)) (decimal-to-base n base true))
([n base reverse?] ([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
(if (or (nil? n) (nil? base) (zero? n) (zero? base)) ;; Allways [0] for base zero or number zero [0]
[0] (loop [acc []
(loop [acc [] x n]
x n] (if (zero? x)
(if (zero? x) (vec (if reverse? (reverse acc) acc)) ;; When x is zero, we have finished
(vec (if reverse? (reverse acc) acc)) ;; When x is zero, we have finished (recur
(recur (conj acc (rem x base)) ;; Accumulate the remainder
(conj acc (rem x base)) ;; Accumulate the remainder (quot x base))))))) ;; Pass the quotient to the next step
(quot x base)))))))) ;; Pass the quotient to the next step
(comment (comment
(decimal-to-base 8 2) (decimal-to-base 8 2)
2r1000 2r1000
) )
(defn base-to-decimal (defn base-to-decimal
"Converts from an array with values in an arbitrary base into decimal values" "Converts from an array with values in an arbitrary base into decimal values"
[n base] [n base]
(if (or (nil? n) (nil? base) (zero? (count n))) (if (or (nil? n) (nil? base) (zero? (count n)))
0 0
(int (reduce-kv (long (reduce-kv
(fn [acc k v] (fn [acc k v]
(+ acc (* v (m/pow base k)))) (+ acc (* v (m/pow base k))))
0 (vec (reverse n)))))) 0 (vec (reverse n))))))
(comment (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) (base-to-decimal [1 0 0 0] 2)
) )
(defn int->varint (defn int->varint
"Converts a integer value to a varint, that is encoded in 7 bits, where the first "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. bit is used to indicate if there are more bytes.
@@ -143,44 +157,64 @@
(bit-and 2r01111111 (peek b128)))))) (bit-and 2r01111111 (peek b128))))))
(defn to-fancy-bin (defn varint->int
"Return a string with bits from number in a fancy manner" "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] [x]
(s/join " " (base-to-decimal (reverse (map #(bit-and 2r01111111 %) x)) 128))
(map s/join
(partition 8 (b2/encode (byte-array (map #(b/to-byte %) x)))))))
(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 (comment
(hex/decode (String/format "%08x" (into-array [1023]))) (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 150))
(to-fancy-bin (int->varint 151)) (to-fancy-bin (int->varint 151))
(to-fancy-hex (int->varint 150)) (to-fancy-hex (int->varint 150))
(to-fancy-hex (int->varint 151) 4) (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 Long/MAX_VALUE))
(to-fancy-bin (int->varint (dec Long/MAX_VALUE))) (to-fancy-bin (int->varint (dec Long/MAX_VALUE)))
(to-fancy-hex (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]) (to-fancy-bin [2r10010110 2r00000001])
[2r10010110 2r00000001] [2r10010110 2r00000001]
[2r0010110 2r0000001] [2r0010110 2r0000001]
) )

View File

@@ -5,7 +5,8 @@
[alphabase.bytes :as b] [alphabase.bytes :as b]
[alphabase.base16 :as hex] [alphabase.base16 :as hex]
[alphabase.base64 :as b64] [alphabase.base64 :as b64]
[alphabase.base32 :as b32])) [alphabase.base32 :as b32])
(:import (java.util Arrays)))
(deftest len-bits-test (deftest len-bits-test
@@ -63,6 +64,7 @@
) )
) )
(deftest base-to-decimal-test (deftest base-to-decimal-test
(testing "Convert from arbitrary base to decimal" (testing "Convert from arbitrary base to decimal"
(is (zero? (base-to-decimal nil 2))) (is (zero? (base-to-decimal nil 2)))
@@ -75,9 +77,48 @@
) )
) )
(deftest decimal-base-decimal-test (deftest decimal-base-decimal-test
(testing "Check if convert from decimal to a base and back preserves the original number" (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 (= 8 (base-to-decimal (decimal-to-base 8 2) 2)))
(is (= 127 (base-to-decimal (decimal-to-base 127 2) 2))) (is (= 127 (base-to-decimal (decimal-to-base 127 2) 2)))
(is (= 417 (base-to-decimal (decimal-to-base 417 13) 13))) (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))))
)
)