谷歌的protocol buffer以其轻量级和跨平台的性质,成为了游戏中数据传输的首选。序列化的过程可以参考该文章 ,还有官方的解释https://developers.google.com/protocol-buffers/docs/encoding。
一、反序列化pb数据可行性分析
传统的pb序列化与反序列化:
序列化: 协议文件(.proto) + 原始数据 ==> 序列化后数据
反序列化: 序列化后数据 + 协议文件(.proto) ==> 原始数据
以传统方式,需要.proto文件才能反序列化出原始数据。但是通过了解序列化的过程,可以知道其实序列化时是按照下列对应类型序列化数据的,那么如果对每个type都能有对应的方法反序列化出原始数据,那么就能够反序列化出整个原始数据。
Type | Meaning | Used For |
---|---|---|
0 | Varint | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
1 | 64-bit | fixed64, sfixed64, double |
2 | Length-delimit | string, bytes, embedded messages, packed repeated fields |
3 | Start group | Groups (deprecated) |
4 | End group | Groups (deprecated) |
5 | 32-bit | fixed32, sfixed32, float |
二、反序列化pb数据例子分析
pb的序列化方式采用了如下方式,K-V KEY-VALUE
或 K-L-V KEY-LENGHT-VALUE
,好像也有叫 T-V TAG-VALUE
和 T-L-V TAG-LENGTH-VALUE
。
Key 的定义如下:
(field_number << 3) | wire_type
其中field_nuber 代表pb中的第几个数据,wire_type 从上面的表格可以知道其数值在0-5区间内
代表该数据的类型。
Intel CPU的架构是小端模式 ,最低字节在前(Small-Endian)
下面是某个pb数据反序列化分析过程,这个分析过程中需要先了解Varint编码方式,UTF8编码方式:
- Varint编码方式
-
UTF8编码方式
Unicode/UCS-4 bit数 UTF-8 byte数 备注 0000 ~007F 0~7 0XXX XXXX 1 0080 ~07FF 8~11 110X XXXX10XX XXXX 2 0800 ~FFFF 12~16 1110XXXX10XX XXXX10XX XXXX 3 基本定义范围:0~FFFF 1 0000 ~1F FFFF 17~21 1111 0XXX10XX XXXX10XX XXXX10XX XXXX 4 Unicode6.1定义范围:0~10 FFFF 20 0000 ~3FF FFFF 22~26 1111 10XX10XX XXXX10XX XXXX10XX XXXX10XX XXXX 5 说明:此非unicode编码范围,属于UCS-4 编码早期的规范UTF-8可以到达6字节序列,可以覆盖到31位元(通用字符集原来的极限)。尽管如此,2003年11月UTF-8 被 RFC 3629 重新规范,只能使用原来Unicode定义的区域, U+0000到U+10FFFF。根据规范,这些字节值将无法出现在合法 UTF-8序列中 400 0000 ~7FFF FFFF 27~31 1111 110X10XX XXXX10XX XXXX10XX XXXX10XX XXXX10XX XXXX -
分析过程
45 00 1A 0F 38 35 37 35 34 32 30 35 32 39 2E 33 34 39 36 22 0C E5 B9 BF E4 B8 9C E6 B7 B1 E5 9C B3 08 CB 8A 01 12 20 36 38 61 31 35 36 66 62 38 66 34 65 64 38 31 63 65 61 31 32 37 37 37 61 34 34 30 32 64 38 34 35
45 00 协议长