开发者工具 · JSON / 数据格式

Protobuf 解析

proto 定义 + 二进制→JSON

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 51 次使用
proto 定义 + 二进制 → JSON · wire format 解码 · 全本地
二进制编码 解析模式
.proto 定义 未解析 .proto
Protobuf 二进制 hex
0 字节
解析结果 decoded
输入二进制后,右侧顶栏可在「树形 / JSON」间切换。
输入二进制即实时解码为 wire format 字段(编号 + 类型 + 值)
RESULTwire format · 字段编号 / 类型 / 值
解析结果将以树形结构展示:每个字段的编号、wire type、推断类型与值;length-delimited 自动递归尝试嵌套 message。
示例:点 08 96 01 → field 1 varint 150 · 12 07 testing → field 2 "testing" · 嵌套 message
就绪 · 输入 protobuf 二进制即时解码
第一节

关于本工具

About

调试 gRPC 接口时,最怕的是拿到一串二进制 protobuf 数据却不知道里面是什么。把 .proto 定义文件和二进制数据贴进去,它实时解析成可读的 JSON 结构,字段名、嵌套层级、枚举值一一对应。解析过程在服务器端完成,原始数据不会被记录或存储——适合对接第三方 API 时快速验证编码是否正确。

使用场景

联调定位字段错位

客户端上报的日志里,用户 ID 和订单金额混在一起,后端解析出的 JSON 字段名对不上。联调群里两边各执一词,谁都不承认序列化顺序写错。把双方 proto 定义同时粘贴进来,再丢入二进制报文,工具直接按定义反序列化出字段名和值,一眼看出服务端多塞了一个 int32 导致后续字段偏移,五分钟定位问题。

旧版本 proto 兼容验证

后端升级了 proto 文件,新增了三个 optional 字段,但线上还有 30% 的旧版客户端没更新。运维需要确认旧版发来的二进制在新 proto 下能否正常解析,不崩也不丢核心字段。把新旧两版 proto 定义分别贴入,用同一段旧版二进制报文跑两遍,对比输出 JSON 的结构差异,确认旧版缺失的字段被正确填了默认值,核心字段完整,才敢灰度上线。

抓包报文人工难读

从 Wireshark 里拷出一段 TCP 载荷,十六进制数据 300 多字节,全是 08 12 1A 这种字节码。开发想确认里面是否包含用户的手机号字段,但手算 varint 和字段 tag 太慢,容易数错偏移。把 proto 定义和十六进制串一起丢进去,工具自动按 field number 和 wire type 拆出每个字段的值,直接看到第 5 个字段是 string 类型,内容正是手机号,省去半小时手工推算。

单元测试构造 protobuf 载荷

写单元测试时,需要构造一个包含嵌套 message 的 protobuf 二进制 payload,但手拼字节流容易错。先用 proto 定义声明好结构,再在工具里填入期望的字段值(如用户 ID=1024,订单金额=99.8),工具自动生成对应的二进制字节串。直接把这个字节串塞进测试用例的 mock 输入,省去写序列化代码的环节,且保证构造的二进制合法。

第三方 SDK 协议逆向

接了一个第三方支付 SDK,文档只给了 proto 文件,但线上抓包发现实际报文里多了一个 unknown field。怀疑是 SDK 内部加了调试字段,但对方不承认。把二进制报文和官方 proto 定义输入工具,解析结果里标出 unknown field 的 field number 和 raw bytes,截图发给对方技术,对方才承认是内部版本号字段忘记在文档里公开,省去反复扯皮。

第二节

使用指南

Getting Started

使用步骤

  1. 1在「Proto 定义」输入框粘贴 .proto 文件内容(支持 message、enum、oneof 等语法),右侧编辑器同步高亮检查语法错误
  2. 2在「二进制数据」输入框粘贴 Base64 编码或原始字节(十六进制字符串),下方提示当前数据长度与格式识别结果
  3. 3点击「解析」按钮,结果区即时输出 JSON 格式的结构化数据,字段名与 proto 定义中的 message 字段一一对应
  4. 4若解析失败,错误提示区显示具体行号与原因(如字段类型不匹配、缺少必填字段),可对照 proto 定义修正后重新提交

输入输出示例

输入输出说明
proto: message Person { optional string name = 1; optional int32 age = 2; optional string email = 3; } bin: 0x0a046a6f686e10190a0a6a6f686e40656d61696c{"name":"john","age":25,"email":"john@email"}常规:标准 proto3 消息,包含 string、int32 字段,验证基本字段解析与顺序
proto: message Test { repeated int32 ids = 1; } bin: 0x0a03010203{"ids":[1,2,3]}常规:repeated 字段(packed 编码),验证数组类型正确解析
proto: message Empty {} bin: 0x{}边界:空消息(无字段定义),验证空输入输出空对象
proto: message Large { optional string big = 1; } bin: 0x0a00000a0000{"big":""}边界:字段值为空字符串(长度 0),验证空值不丢失字段
proto: message Nested { message Inner { optional int32 x = 1; } optional Inner inner = 1; } bin: 0x0a020801{"inner":{"x":1}}边界:嵌套消息,验证递归解析与层级结构
proto: message EnumTest { enum Color { RED = 0; GREEN = 1; } optional Color c = 1; } bin: 0x0801{"c":"GREEN"}易错:枚举值解析为字符串名称而非数字,需注意枚举值 0 的默认行为
proto: message Mixed { optional float f = 1; optional double d = 2; optional bool b = 3; } bin: 0x0d0000204209110000000000000040{"f":40.0,"d":2.5,"b":true}易错:浮点数与布尔值的二进制表示(小端序、IEEE 754),验证浮点精度与布尔值映射

常见错误对照

1.二进制数据未做 Base64 编码直接粘贴

✗ 错误直接粘贴原始二进制字节(如 0x0A 0x1B 等十六进制文本)
✓ 修复将二进制数据先转换为 Base64 字符串(如使用 base64 命令或在线工具)再粘贴

本工具输入框接受文本,二进制数据包含不可见字符,直接粘贴会破坏数据完整性。Base64 是 protobuf 官方推荐的二进制文本传输编码。

2.proto 定义中字段类型与二进制数据不匹配

✗ 错误proto 定义字段为 int32,但二进制数据对应的是 sint32 编码的负数
✓ 修复确保 proto 字段类型与编码端一致,负数用 sint32 或 sfixed32,uint32 无法表示负数

Protobuf 的编码方式因类型而异:int32 对负数用 10 字节 zigzag 编码,而 sint32 用变长 zigzag。类型不匹配会导致解析出错误值或解析失败。

3.proto 定义中字段编号与二进制数据不对应

✗ 错误二进制数据中字段编号为 5,但 proto 定义中编号 5 对应的字段类型是 string
✓ 修复核对二进制数据生成端 proto 文件,确保字段编号和类型完全一致

Protobuf 二进制流通过 field_number + wire_type 识别字段。编号相同但类型不同时,解析器会按 proto 定义的类型读取,导致数据错位或乱码。

4.忘记处理 repeated 字段的 packed 编码

✗ 错误proto 定义 repeated int32 ids = 1,二进制数据是 packed 编码,但 proto 未加 [packed=true]
✓ 修复在 proto 定义中明确标注 packed 属性:repeated int32 ids = 1 [packed=true];

Protobuf 3 默认对基本类型 repeated 字段启用 packed 编码。如果 proto 2 未声明 packed,解析器会按非 packed 格式读取,导致字段解析为多个独立值而非数组。

5.未区分 oneof 字段导致多值冲突

✗ 错误proto 定义 oneof 包含 string name 和 int32 age,二进制数据同时包含两者
✓ 修复确保 oneof 字段在二进制数据中只出现其中一个,或检查生成端逻辑

Protobuf oneof 语义是互斥的,同时设置多个字段会导致最后一个覆盖前面的。解析时只会保留最后一个出现的字段,其余被静默丢弃。

6.map 字段的 key 类型使用浮点数

✗ 错误proto 定义 map<double, string> scores = 1;
✓ 修复map 的 key 必须使用整数或字符串类型:map<string, string> scores = 1;

Protobuf 规范明确禁止浮点数、bytes、enum 作为 map 的 key 类型。浮点数存在精度和相等比较问题,编译 proto 文件时会直接报错。

7.忽略 enum 值的默认行为

✗ 错误二进制数据中 enum 字段值为 0,但 proto 中 0 对应的枚举名是 UNKNOWN
✓ 修复确认业务逻辑中 0 值 enum 的含义,必要时在 proto 中将 0 定义为有效值

Protobuf 3 中,未设置的 enum 字段默认值为 0。如果 0 对应的枚举名是 UNKNOWN,解析结果会显示 UNKNOWN,可能被误认为数据异常。

8.嵌套 message 的二进制数据未正确拼接

✗ 错误将外层 message 和内层 message 的二进制数据直接拼接后传入
✓ 修复按 protobuf 序列化规则,内层 message 作为外层的一个字段整体序列化,不可拆分

嵌套 message 在二进制中是一个 length-delimited 字段,内层数据作为 bytes 整体嵌入。手动拼接会破坏字段边界,导致解析时字节错位。

第三节

工作原理

How It Works

核心公式

JSON = decode(proto, binary) 其中 decode 按 proto 定义的字段类型、顺序、嵌套规则将二进制数据反序列化为 JSON 对象

变量说明

  • protoProtocol Buffers 的 .proto 定义文本
  • binaryBase64 编码或原始字节的 Protobuf 序列化数据
  • JSON解码后输出的结构化 JSON 对象

示例

proto 定义:message Person { required int32 id = 1; required string name = 2; };binary 为 Base64 编码的字节流 CgVhZG1pbhAB(对应 id=1, name="admin")。解码过程:按 proto 字段顺序读取 tag 1(int32 类型,值 1)和 tag 2(length-delimited 字符串,长度 5,内容 "admin"),组装为 JSON:{"id":1,"name":"admin"}。

用户输入Proto 定义 + 二进制后端解析按 proto 拆字段输出结果JSON 格式校验字段合法性类型 / 范围 / 必填二进制数据Base64 / Hex / Raw
用户输入 后端处理 输出结果 中间数据 / 校验
第五节

常见问题

Q & A
我只有 .proto 文件,没有二进制数据,能用这个工具吗?

不能直接使用。本工具需要同时提供 .proto 定义文件(描述消息结构)和对应的序列化二进制数据(如 gRPC 响应体、Kafka 消息体等),才能将二进制解析为 JSON。如果仅有 .proto 文件,可先用其他工具生成模拟二进制数据,或确认数据源是否已提供序列化后的字节流。

我的 proto 文件里用了 import,工具能自动处理吗?

本工具目前仅支持单个 .proto 文件解析,不支持自动解析 import 语句。如果 .proto 文件依赖其他类型(如 google/protobuf/timestamp.proto),需要将这些依赖的 .proto 文件内容手动合并到主文件内,或精简掉无关 import 后上传。建议在提交前用 protoc 命令验证合并后的文件是否合法。

解析出来的 JSON 里字段名为什么是下划线风格而不是驼峰?

这是由 .proto 定义中的字段名直接决定的。Protobuf 默认使用下划线命名(如 user_name),工具不做额外转换。如果期望输出驼峰格式(如 userName),需要在 .proto 文件中显式声明 json_name 选项,例如:string user_name = 1 [json_name = "userName"];否则字段名与 .proto 保持一致。

二进制数据有几千字节,传上去会不会很慢?

本工具为后端 Go 实现,处理 10MB 以内的二进制数据通常在 1-3 秒内完成,具体取决于 .proto 定义的复杂度(如嵌套消息数量、重复字段层级)。超过 50MB 的二进制数据建议分块处理或使用本地 protoc 命令,因为 HTTP 传输本身会占用较多时间。工具对单次请求的二进制大小限制为 100MB。

为什么解析出来的时间戳是整数而不是可读的日期?

Protobuf 标准中时间戳字段通常定义为 google.protobuf.Timestamp 类型,其序列化后是秒和纳秒两个整数。本工具目前直接输出这两个整数字段,不自动格式化为可读日期。如需可读时间,可在 .proto 中改用 string 类型并自行定义时间格式,或解析后使用外部脚本转换。

我上传的二进制和 proto 文件都是正确的,但解析结果全是空对象,怎么回事?

常见原因有两种:一是二进制数据可能经过了 base64 编码,但工具要求的是原始字节流,需要先解码为二进制再上传;二是 .proto 定义中的字段编号与二进制数据实际使用的编号不一致(例如 proto 文件已更新但二进制是旧版本生成的)。建议先用 protoc --decode_raw 命令验证二进制是否能被正确解码。

这个工具会把我的 proto 和二进制数据存到服务器上吗?

不会。工具采用后端 Go 实现,数据仅在内存中完成解析后立即返回结果,不会写入磁盘或数据库。解析完成后,服务器端的内存会被回收,不会留存任何用户数据。但出于网络传输安全考虑,建议不要在二进制数据中包含敏感信息(如密码、密钥),如需处理敏感数据可考虑本地部署的 protoc 工具。

和 protoc 命令比,这个工具有什么优势?

主要优势是免安装、免配置。使用 protoc 需要本地安装 Protobuf 编译器、配置包含路径、处理依赖,对不熟悉命令行的开发者有一定门槛。本工具直接在浏览器中操作,上传文件即可得到结果,适合快速调试或临时验证。但 protoc 支持更复杂的选项(如自定义输出格式、多文件依赖解析),适合集成到构建流程中。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭