#前言

解析 varint:

varint 是变长整数,如果数组中的数大小不均匀时用 varint 会比较高效。

本质上是将一个字节的低七位用于存储数据,最高一位用于标识是否该数字已结束。

比如二进制1111111 1010101 0101010000 11111,如果用相同的大小存,第二个数字会用很多无用的零空间。

转化成 varint 的逻辑如下:

  1. 按七个比特位分割,111111110101010101010
  2. 小端序,低位在前,010101010101011111111
  3. 第一、二个最前面补 1,最后一个补 0,101010101101010101111111

#解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func DecodeVarint(buf []byte) (x uint64, n int) {
for shift := uint(0); shift < 64; shift += 7 {
if n >= len(buf) {
return 0, 0
}
b := uint64(buf[n])
n++
x |= (b & 0x7F) << shift
if (b & 0x80) == 0 {
return x, n
}
}
return 0, 0
}

解码是逆过程,取出七位的有效位数,并左移,越往后的数字 shift 的位数越多,因为编码的时候,越大的位数在整个 varint 的越后面。

直到首位是 0,代表一个数字结束,返回。

#疑问点

  1. 在编码的时候需要把不足的位数补回去吗?感觉是需要的,但是没找到证据= =

#最后

  1. 炉石的卡牌代码就是 varint+base64,之前一直用 shell 调用 python 的解析库,实在是太慢了,研究一下,一小时搞定。
  2. 最近优化了很多项目上的东西,比如把 shell 调用换成了 go 语言重写,之前 7 秒的一个接口请求现在估计 1 秒就渲染好了= =

#参考链接