博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
无protobuf协议情况下的反序列化------貌似无解, 其实有解!
阅读量:4139 次
发布时间:2019-05-25

本文共 2296 字,大约阅读时间需要 7 分钟。

        用过protobuf的人都知道, protobuf的序列化过程是:

        协议文件(.proto) + 原始数据 ====》 buffer

        反序列化的过程是:

        buffer + 协议文件(.proto) ===>原始数据

 

        那有没有办法实现: buffer ===》原始数据  呢?   这是一个貌似无解的问题, 其实有解。  

        如果在无协议的情况下, 能实现buffer到原始数据的转化, 那就具有非常重要的意义: 抓包后(抓16进制), 可直接转换成原始数据!!! Oh, my god,  效率呈现指数级提升!!! 着实让人兴奋大哭大哭大哭

   

         之前我学过h.264视频压缩, 原始的yuv数据经过h.264压缩后, 生成压缩视频, 每个字节都有其固定含义, 因此可解码。 类似地, 在protobuf序列化过程中, 也有这样的道理。 序列化后的每个字节都有固定含义, 那么自然就可以对这些有固定意义的字节进行解码, 我们来看看代码:

         test.proto内容:

 

package NS;  message PointReq {      required int32 x=1;      required int32 y=2;  }taoge@localhost Desktop>

 

        main.cpp内容:

 

#include 
#include
using namespace std;#include "test.pb.h"using namespace NS;// 16进制string bufToHexStr(const char *pBuf, int bufLen){ if(NULL == pBuf || bufLen < 0) { return ""; } int i = 0; string sRet = ""; for(i = 0; i < bufLen; i++) { char szTmp[3] = {0}; snprintf(szTmp, sizeof(szTmp), "%02x", (unsigned char)pBuf[i]); sRet += szTmp; } return sRet;}int main(){ PointReq point; point.set_x(10); point.set_y(20); string tmp; bool ret = point.SerializeToString(&tmp); // 这里要传地址 if (ret) { printf("encode ok!\n"); } else { printf("encode error!\n"); return -1; } cout << bufToHexStr(tmp.c_str(), tmp.size()) << endl; PointReq point2; ret = point2.ParseFromString(tmp); if (ret) { printf("decode ok, %d, %d\n", point2.x(), point2.y()); } else { printf("decode error!\n"); return -2; } return 0;}

 

       结果:

 

taoge@localhost Desktop> make g++   -c  -L/usr/local/lib   -lprotobuf   -o main.o main.cpp  g++   -c  -L/usr/local/lib   -lprotobuf   -o test.pb.o test.pb.cc g++: -lprotobuf: linker input file unused because linking not doneg++: -lprotobuf: linker input file unused because linking not doneg++    -L/usr/local/lib   -lprotobuf   -o main main.o test.pb.o  taoge@localhost Desktop> ./main encode ok!080a1014decode ok, 10, 20

       

       上面反序列化依赖于test.proto协议文件。 

 

 

        下面, 我们不依赖于test.proto协议文件(仅仅利用序列化的结果080a1014)来反序列化一下:

        如果协议是嵌套的, 那么此处的展示结果也是嵌套的, 有缩进关系, 非常好看, 爽心悦目大笑

 

        这个无协议序反序列化工具是某哥开发的, 所以我就不贴源码了。 无协议反序列化真的很有创意羡慕我们工作中, 每个人每天都有多次使用。 

        当然, 在你的公司, 很可能不用protobuf, 而是用自己公司开发的序列化协议框架, 那也一样, 无协议时可反序列化。有兴趣的朋友可以试着写一下无协议时的反序列化代码(一个字节一个字节地抠), 代码量其实很少! 

 

 

 

你可能感兴趣的文章
idea的安装以及简单使用
查看>>
Windows mysql 安装
查看>>
python循环语句与C语言的区别
查看>>
vue 项目中图片选择路径位置static 或 assets区别
查看>>
vue项目打包后无法运行报错空白页面
查看>>
Vue 解决部署到服务器后或者build之后Element UI图标不显示问题(404错误)
查看>>
element-ui全局自定义主题
查看>>
facebook库runtime.js
查看>>
vue2.* 中 使用socket.io
查看>>
openlayers安装引用
查看>>
js报错显示subString/subStr is not a function
查看>>
高德地图js API实现鼠标悬浮于点标记时弹出信息窗体显示详情,点击点标记放大地图操作
查看>>
初始化VUE项目报错
查看>>
vue项目使用安装sass
查看>>
HTTP和HttpServletRequest 要点
查看>>
在osg场景中使用GLSL语言——一个例子
查看>>
laravel 修改api返回默认的异常处理
查看>>
laravel事务
查看>>
【JavaScript 教程】浏览器—History 对象
查看>>
这才是学习Vite2的正确姿势!
查看>>