最近在研究某游戏封包,里面的一个可变数据长度的数字值我没办法找到解码规律,他看起来像是使用protobuf序列化后的数据,但是根据protobuf规则解码,结果又不对。例如04 ce 25
表示十进制的10021
,而如果按照protobuf规律解码,应该是得到12ce
,即4814
。这个地方卡了我好几天,想破头也想不到思路。
后来看了这个文章https://blog.csdn.net/qq_38410730/article/details/103702827 ,里面提到了protobuf对于正数的编码采用varint,对于负数的编码采用ZigZag编码后的varint。
,因为负数使用zigzag编码更节省字节数。我突然想到会不会这游戏把正数也是先zigzag再varint呢。验证后确定是先zigzag,然后是个不完整的varint过程,不完整
处是他解码时不需要调整为大端序。
解码过程:
CE25 => 11001110 00100101
第一个字节去掉首位的1,然后逆zigzag(右移1位),得到:100111 00100101 => 10021
之前看的关于protobuf的文章都没有提到过zigzag,所以卡了好几天才解决这个问题。