SQLite 变长度整型(varint)编码解码方法

来源:互联网 发布:unity3d前景怎么样 编辑:程序博客网 时间:2024/05/20 07:32

SQLite为了节省存储空间,可以对64-bits的整型变量进行压缩。压缩后的最后一个byte的第一个bit是0,其他byte的第一个bit都是1,如下:


对于十进制数 182, 它的二进制是 10110110, 有8个bit,但是第一个bit是1,所以对其分割:


分割成两个bytes, 填充这两个bytes,使得他们符合上面提到的规则(加粗部分):


这样十进制整数 182 就被编码为一个2bytes的二进制格式了。

解码只需要把这个过程逆过来进行一遍就可以了。

还有需要注意的一点是SQLite是对64-bits的整型变量的二进制补码进行编码的,这对正数没什么影响,但是对负数编码的时候需要注意一下。


附上我的编码解码代码,我没使用补码,默认数据都是非负数:

unsigned char* IntToVar(unsigned char* dst, uint32_t v){unsigned char* ptr = dst;static const int B = 128;if (v < (1 << 7)){*(ptr++) = v;}else if (v < (1 << 14)){*(ptr++) = v | B;*(ptr++) = v >> 7;}else if (v < (1 << 21)){*(ptr++) = v | B;*(ptr++) = (v >> 7) | B;*(ptr++) = v >> 14;}else if (v < (1 << 28)){*(ptr++) = v | B;*(ptr++) = (v >> 7) | B;*(ptr++) = (v >> 14) | B;*(ptr++) = v >> 21;}else{*(ptr++) = v | B;*(ptr++) = (v >> 7) | B;*(ptr++) = (v >> 14) | B;*(ptr++) = (v >> 21)|B;*(ptr++) = v >> 28;}return ptr;}uint32_t VarToInt(unsigned char* tail){unsigned char* pTmp = tail;uint32_t Res=0;while ((*pTmp) & 128 == 128) {Res = Res << 7;*pTmp = *pTmp ^ 128;Res = Res | (*pTmp);pTmp--;}Res = Res << 7;Res = Res | *pTmp;return Res;}


0 0
原创粉丝点击