probuf 流无协议文件反序列化

最近解码了一个没有协议(.proto)文件的probuf包,遇到了以下的一些问题:

  1. 不清楚probuf的基础知识;
  2. 不清楚probuf的序列换和反序列化规则;
  3. 没有合适的调试工具;
  4. 不熟悉java里probuf流的操作;

解决了以上几个问题,问题也就迎刃而解了!

 

一、不清楚probuf的基础知识

官方定义:

protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。
 

       主要了解到protobuf的基础定义,使用场景,一些规则,再结合一个实例这块就算解决了。

详细介绍可以在以下地方了解:

probuf详解:https://blog.csdn.net/weixin_42018112/article/details/89633837

深入 ProtoBuf - 简介:https://www.jianshu.com/p/a24c88c0526a

ProtoBuf结合java快速入门:https://www.jianshu.com/p/bb3ac7e5834e

 

二、不清楚probuf的序列换和反序列化规则

        正常情况下我们需要协议文件,也就是生成probuf流时建立的 .proto文件,根据这个文件,我们可以解出来Message对应的每个字段的信息。官方给了一个命令,可以在无 .proto文件的情况下,解出probuf流的内容: protoc --decode_raw。

import subprocess
def decode(data):
    process = subprocess.Popen([r'D:\protobuf\protoc.exe', '--decode_raw'],
    stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

    output = error = None
    try:
        output, error = process.communicate(data)
    except OSError:
        pass
    finally:
        if process.poll() != 0:
            process.wait()
    return output

f = open(r"D:\testprotobuf.bin", "rb")
data = f.read()
print('data:/n',decode(data))

详细介绍可以在以下地方了解:

无protobuf协议情况下的反序列化------貌似无解, 其实有解!:https://blog.csdn.net/stpeace/article/details/53047424

protobuf流的反解析Message:https://blog.csdn.net/liujiayu2/article/details/77838761

三、没有合适的调试工具

       了解完基础知识以后,我们就可以动手进行解码的尝试了。由于网上没有一些在线的工具(像beJSON)可以辅助我们判断自己的尝试是否正确,直接在代码里尝试,每一次修改,启动,都不太好确定是哪里出了问题,所以我们先在一些在线调试工具中确定了我们的probuf流是正确的,我们推导出的.proto文件也是正确的,再进行编码。

我们现有的protobuf流是一个16进制的流:

08 d0 02 10 c3 80 80 80 80 80 80 02 1a 0e 0a 0c e5 be ae e8 bd af e9 9b 85 e9 bb 91 22 4c 08 bd f3 0b 12 06 e8 8a ac e5 85 b0 1a 18 77 c9 35 5a 0e 0c 3b 40 1c d7 c2 bc c7 2b 50 40 00 00 00 00 00 00 2c 40 20 00 50 ff ff ff ff ff ff ff ff ff 01 59 00 00 00 00 00 00 3e 40 60 80 80 80 f8 0f 68 00 70 1e 78 ff ff ff ff 0f 22 4f 08 a1 f4 0b 12 09 e4 b9 8c e5 85 8b e5 85 b0 1a 18 02 37 db 85 e6 7a 40 40 b0 59 3c 87 32 80 48 40 57 b3 09 97 5c 3b 5f 40 20 00 50 ff ff ff ff ff ff ff ff ff 01 59 00 00 00 00 00 00 3e 40 60 80 80 80 f8 0f 68 00 70 1e 78 ff ff ff ff 0f

      通过两个工具:Protobuf Decoder 和 Online Protobuf encoder/decoder,就可以很方便的确定我们的probuf流是否正确,我们推导出的.proto文件是否正确。Protobuf Decoder不需要协议文件(.proto)可以解析出我们的数据内容,Online Protobuf encoder/decoder可以判断我们推导出的协议文件是否正确。

probuf 流无协议文件反序列化_第1张图片

 probuf 流无协议文件反序列化_第2张图片

上述工具资源地址:

 无协议文件解码工具decode:https://download.csdn.net/download/qq_25073789/12334831

 通过协议文件编码解码流工具: https://download.csdn.net/download/qq_25073789/12334839

四、不熟悉java里probuf流的操作

       proto文件准备就绪,java代码也通过protoc命令生成后,我们读取16进制流文件对其进行反序列化。反序列化的接受格式为byte[],所有我们使用BufferedInputStream进行文件读取,以下代码为读取probuf流的方法。反序列化和生成java文件的方法参考教程。

public static byte[] readFile(File file) throws Exception {
    if (file.exists() && file.isFile()) {
	    long fileLength = file.length();
		if (fileLength > 0L) {
			BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
			byte[] b = new byte[(int) fileLength];
			fis.read(b);
			fis.close();
			fis = null;			
			return b;
		}
	} else {
		return null;
	}
	return null;
}

java代码参考:

java中使用ProtoBuf的Demo: https://www.cnblogs.com/jpfss/p/10881357.html

你可能感兴趣的:(地理信息,javascript,解码,protobuf,无proto文件解码,protobuf-decode,protobuf数据流解析)