VINT编码
VInt 编码为 Varint 编码和 ZigZag 编码的结合,本质思想是字节数动态变化的整数,笼统的说就是较小的正整数值将占用较小的空间,其可将 64 位二进制编码的有符号整型编码用 1 到 10 字节表示。例如,在Cpp中int 类型的数据都由固定的 4 字节表示,这样设计的好处是序列化和反序列化简单,但是如果需要存储大量的整数,特别是数值较小的整数占比较大时,会浪费掉许多存储空间。基于此,我们可以采用VINT编码来存储整型数据,从而实现数据压缩,节约存储空间。下面介绍具体的原理。
VINT编码原理
Varint 编码
Varint 编码为一种将 64 位二进制编码的无符号整型根据其大小用不同长度
字节进行编码的编码方式。
编码的规则如下:标志位(1bit)+数据位(7bit)。
10000001//第一位为标志位,后七位为数据位
其中每个字节的低 7 位用来表示数值;最高位(第一位)为标志位,1表示后面还有字节数据,且依然为该数值的部分字节, 0表示该字节为该数值的最后一个字节。
00000001 //最高位为0,表示该字节为最后一个字节
10000001 //最高位为1,表示该字节后面还有数据
因此,数字越小,其编码所占用的字节数越少;数字越大,所占字节数越多。
ZigZag编码
ZigZag 编码主要是用来配合 Varint 编码。ZigZag编码将有符号整数映射到无符号整数。这里我们以long类型(64bit)为例,具体的算法如下
ZigZag(n) = (n<<1)^(n>>63)
结果ZigZag编码后,有符号整数映射到无符号整数,如下,
原始数据 | ZigZag编码后 |
---|---|
0 | 0 |
1 | 1 |
-1 | 2 |
2 | 3 |
-2 | 4 |
… | … |
-2147483648 | 4294967295 |
VINT编码过程
- 基于 ZigZag编码将数据类型变为无符号型。这里我们以-8为例:
负数-8的二进制为:
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111000
采用ZigZag 编码,变为无符号整数后,其二进制为:
00000000 00000000 00000000