✅

以下是一个纯 PHP 编写的通用 Protobuf 二进制生成器,支持:

  • varint

  • fixed32

  • fixed64

  • length-delimited(如字符串、嵌套 message)

  • 嵌套结构 (nested)

  • 多字段 repeated


✅ 封装器代码(可直接用)

<?phpfunction writeVarint($value) {$result = '';while (true) {if (($value & ~0x7F) === 0) {$result .= chr($value);break;} else {$result .= chr(($value & 0x7F) | 0x80);$value >>= 7;}}return $result;
}function writeFieldHeader($fieldNum, $wireType) {return writeVarint(($fieldNum << 3) | $wireType);
}function writeVarintField($fieldNum, $value) {return writeFieldHeader($fieldNum, 0) . writeVarint($value);
}function writeFixed32Field($fieldNum, $hex) {if (strlen($hex) !== 8) throw new Exception("fixed32 hex 必须为 8 位");return writeFieldHeader($fieldNum, 5) . hex2bin($hex);
}function writeFixed64Field($fieldNum, $hex) {if (strlen($hex) !== 16) throw new Exception("fixed64 hex 必须为 16 位");return writeFieldHeader($fieldNum, 1) . hex2bin($hex);
}function writeLengthDelimitedField($fieldNum, $value) {return writeFieldHeader($fieldNum, 2) . writeVarint(strlen($value)) . $value;
}function buildMessage($fields) {$message = '';foreach ($fields as $field) {$fieldNum = $field['field'];$type = $field['type'];$value = $field['value'];switch ($type) {case 'varint':$message .= writeVarintField($fieldNum, $value);break;case 'fixed32':$message .= writeFixed32Field($fieldNum, $value);break;case 'fixed64':$message .= writeFixed64Field($fieldNum, $value);break;case 'string':$message .= writeLengthDelimitedField($fieldNum, $value);break;case 'bytes':$message .= writeLengthDelimitedField($fieldNum, hex2bin($value));break;case 'nested':$nested = buildMessage($value);  // 递归生成嵌套$message .= writeLengthDelimitedField($fieldNum, $nested);break;default:throw new Exception("不支持的字段类型: $type");}}return $message;
}

示例调用方式

$protobuf = buildMessage([['field' => 1, 'type' => 'varint', 'value' => 123],['field' => 2, 'type' => 'fixed64', 'value' => '0011223344556677'],['field' => 3, 'type' => 'string', 'value' => 'hello'],['field' => 4, 'type' => 'bytes', 'value' => 'deadbeef'],['field' => 5, 'type' => 'nested', 'value' => [['field' => 1, 'type' => 'string', 'value' => 'inner']]]
]);echo base64_encode($protobuf);

 

以下是一个 JSON 转 Protobuf 结构数组 的示例转换器,用于搭配你已有的 buildMessage() 使用:


✅ 1. JSON → PHP 数组结构转换器

🔧 示例 JSON 格式

[{ "field": 1, "type": "varint", "value": 123 },{ "field": 2, "type": "fixed64", "value": "0011223344556677" },{ "field": 3, "type": "string", "value": "hello" },{"field": 4,"type": "nested","value": [{ "field": 1, "type": "string", "value": "inner" }]}
]

✅ 加载并构造的 PHP 代码

function buildFromJson($jsonStr) {$decoded = json_decode($jsonStr, true);if (!is_array($decoded)) {throw new Exception("无效 JSON 格式");}return buildMessage($decoded);
}

✅ 完整示例组合用法:

 
include 'protobuf_builder.php'; // 假设你把封装器写到这个文件里$json = '[{ "field": 1, "type": "varint", "value": 123 },{ "field": 2, "type": "fixed64", "value": "0011223344556677" },{ "field": 3, "type": "string", "value": "hello" },{"field": 4,"type": "nested","value": [{ "field": 1, "type": "string", "value": "inner" }]}
]';$protobuf = buildFromJson($json);
echo base64_encode($protobuf);

✅ 输出说明

这段代码会输出一段 符合 JSON 结构的 Protobuf 二进制串,你可用于发送、调试、对比:

<?php
// CGQQl1oaBTEuMi4xInxleUpOWVhKclNXUWlPakFzSWxSNWNHVWlPakVzSWtGd2NFbGtJam96T0RReE5UZ3NJbFZ6WlhKSlpDSTZOelV3T1RZNE5qWTJOVEk0T1RVMk5USTBNeXdpVkdsdFpYTjBZVzF3SWpveE56VXdPVFUxTmpVME56STFmUT09KAMwADoOYzg5ZThkZjptYXN0ZXJCigaiBoYGCigwOjE6MTg5Mzc3Mzc0NzE3MTc5OTo3NTA5Njg2NjY1Mjg5NTY1MjQzEAEYi4SF1KeN76loIhF7InRleHQiOiLlp5Dlp5AifSo5ChNhOmNsdWVfYjJjX3RpbWVfbG9nEiJ7ImIyY19mZV9zZW5kX3RpbWUiOjE3NTA5NjA4NDc0NjJ9KisKGmE6aW1fZ2VuZXJhbF9zZW5kX21zZ190aW1lEg0xNzUwOTYwODQ3NDYyKiIKEmE6c2VuZF90aW1lX3NvdXJjZRIMY29tbWVyY2VfcHJpKhMKDmNzOm1zZ19jaGFubmVsEgExKhEKDGNzOmNvbnZfbW9kZRIBMSoUCg9jczphY2NvdW50X3R5cGUSATEqDwoKY3M6dG9vbF9pZBIBMCofChNsZWFkc19pbV9jaGF0X3NjZW5lEghjb21tZXJjZSofChNsZWFkc19pbV9tc2dfc2NoZW1hEghjb21tZXJjZSorChdhOnNhaXlhbl9pbV9zZW5kX21ldGhvZBIQQ3NfTGVhZHNQbGF0Zm9ybSoYChRsZWFkc19pbV9iaXpfY2hhdF9pZBIAKicKFWxlYWRzX2ltX21zZ19wbGF0Zm9ybRIObGVhZHNfcGxhdGZvcm0qGAoTbGVhZHNfcGNfZGlyZWN0X21zZxIBMSoVChFzOm1lbnRpb25lZF91c2VycxIAKjsKE3M6Y2xpZW50X21lc3NhZ2VfaWQSJGM4YTc5NDE1LWI4OGMtNGQ4OS1hODExLWExMDhiMTU2NGFkOSodCgdzOnN0aW1lEhIxNzUwOTYwODQ4NzUzLjI0NDEwBzp5MWxhV3h3SU93UkpPd1Zta2NHZXZXcGNNTEhNNXNKU1ZKRUwxbGRnNjB2aWhybERIWGx0clp0TnBIUFJZZHQ3MHp0NHl4Q1llVHNaUmVoMEtYU1dtV1BrYXZLRERWNTZlMlFpNXFjVnRHVXMxU0tJQnU2TTYzS01ZU0IkYzhhNzk0MTUtYjg4Yy00ZDg5LWE4MTEtYTEwOGIxNTY0YWQ5ShM3NTE3ODMxOTE5ODQ3MjEyNTc5UgJtcFoFbXBfcGN6DQoIaXMtcmV0cnkSATCQAQOqAQ5sZWFkc19wbGF0Zm9ybbIBB3dlYl9zZGu6AYUBdHMuMS4yYmQwMmNiOTQ4YzliNjM5ZDY5ODM1ZDQ3ZGY1ODU2MWRjNTUxMTAwMzViY2Q3ZDc1MjQ5ODA1MjJjYzcxMDE4YzRmYmU4N2QyMzE5Y2YwNTMxODYyNGNlZGExNDkxMWNhNDA2ZGVkYmViZWRkYjJlMzBmY2U4ZDRmYTAyNTc1ZMIBXHB1Yi5CUDNSckRuemd5TEdEKzZDOVB4NjhOdkZwTldKVXN6SkM0emg1dDlLbDhjTzJIMHAva2RMcnFXaXA4ZWN2eUpvUXJ5Nktmbk1lYVBZMnBtUnBtTVdaeFk9ygFgTUVVQ0lRQ2dLQnduSFJtWkgxSmxRRzdPVExKeVE2alVacCtDN1Q4cEw5QkhSV0ZmVGdJZ0Z4MWwyMjFoYjdjUC9CS2dGWE5HaWxJaXRoZzc4dkxFSVdkWDhzbWVzaVU9ugYBMcAGz5X2wgY=
function writeVarint($value) {$result = '';while (true) {if (($value & ~0x7F) === 0) {$result .= chr($value);break;} else {$result .= chr(($value & 0x7F) | 0x80);$value >>= 7;}}return $result;
}function writeVarintField($fieldNum, $value) {return writeVarint(($fieldNum << 3) | 0) . writeVarint($value);
}function writeLengthDelimitedField($fieldNum, $value) {return writeVarint(($fieldNum << 3) | 2) . writeVarint(strlen($value)) . $value;
}
function writeFixedField($fieldNum, $hex) {return writeVarint(($fieldNum << 3) | 5) . hex2bin($hex);
}
function writeFixed32Field($fieldNum, $hex4bytes) {if (strlen($hex4bytes) !== 8) throw new Exception("Fixed32 must be 4 bytes (8 hex chars)");return writeVarint(($fieldNum << 3) | 5) . hex2bin($hex4bytes);
}function writeFixed64Field($fieldNum, $hex8bytes) {if (strlen($hex8bytes) !== 16) throw new Exception("Fixed64 must be 8 bytes (16 hex chars)");return writeVarint(($fieldNum << 3) | 1) . hex2bin($hex8bytes);
}function buildField4() {return "eyJNYXJrSWQiOjAsIlR5cGUiOjEsIkFwcElkIjozODQxNTgsIlVzZXJJZCI6NzUwOTY4NjY2NTI4OTU2NTI0MywiVGltZXN0YW1wIjoxNzUwOTU1NjU0NzI1fQ==";
}function buildKeyValueMessage($key, $value) {return writeLengthDelimitedField(1, $key) . writeLengthDelimitedField(2, $value);
}function build8_100_5() {$out = '';$pairs = [['a:clue_b2c_time_log', '{"b2c_fe_send_time":1750960847462}'],['a:im_general_send_msg_time', '1750960847462'],['a:send_time_source', 'commerce_pri'],['cs:msg_channel', '1'],['cs:conv_mode', '1'],['cs:account_type', '1'],['cs:tool_id', '0'],['leads_im_chat_scene', 'commerce'],['leads_im_msg_schema', 'commerce'],[buildNestedKey(), 'Cs_LeadsPlatform'],['leads_im_biz_chat_id', ''],['leads_im_msg_platform', 'leads_platform'],['leads_pc_direct_msg', '1'],['s:mentioned_users', ''],['s:client_message_id', 'c8a79415-b88c-4d89-a811-a108b1564ad9'],['s:stime', '1750960848753.2441']];foreach ($pairs as [$k, $v]) {$entry = buildKeyValueMessage($k, $v);$out .= writeLengthDelimitedField(5, $entry);}return $out;
}function buildNestedKey() {$inner = '';$inner .= writeFixed64Field(12, '3A73616979616E5F');$inner .= writeFixed64Field(13, '6D5F73656E645F6D');$inner .= writeFixed32Field(12, '74686F64');  // ✅ 修正这里为 Fixed32,直接写入return $inner;return writeLengthDelimitedField(1, $inner);
}function build8_100() {$out = '';$out .= writeLengthDelimitedField(1, '0:1:1893773747171799:7509686665289565243');$out .= writeVarintField(2, 1);$out .= writeVarintField(3, 7517559368519336459);$out .= writeLengthDelimitedField(4, '{"text":"姐姐"}');$out .= build8_100_5();$out .= writeVarintField(6, 7);$out .= writeLengthDelimitedField(7, '1laWxwIOwRJOwVmkcGevWpcMLHM5sJSVJEL1ldg60vihrlDHXltrZtNpHPRYdt70zt4yxCYeTsZReh0KXSWmWPkavKDDV56e2Qi5qcVtGUs1SKIBu6M63KMYS');$out .= writeLengthDelimitedField(8, 'c8a79415-b88c-4d89-a811-a108b1564ad9');return $out;
}function buildFinalMessage() {$out = '';$out .= writeVarintField(1, 100);$out .= writeVarintField(2, 11543);$out .= writeLengthDelimitedField(3, "1.2.1");$out .= writeLengthDelimitedField(4, buildField4());$out .= writeVarintField(5, 3);$out .= writeVarintField(6, 0);$out .= writeLengthDelimitedField(7, "c89e8df:master");$out .= writeLengthDelimitedField(8, writeLengthDelimitedField(100, build8_100()));$out .= writeLengthDelimitedField(9, "7517831919847212579");$out .= writeLengthDelimitedField(10, "mp");$out .= writeLengthDelimitedField(11, chr((13 << 3) | 5) . hex2bin("705F7063"));$out .= writeLengthDelimitedField(15, writeLengthDelimitedField(1, "is-retry") . writeLengthDelimitedField(2, "0"));$out .= writeVarintField(18, 3);$out .= writeLengthDelimitedField(21, "leads_platform");$out .= writeLengthDelimitedField(22, "web_sdk");$out .= writeLengthDelimitedField(23, hex2bin("74732E312E3262643032636239343863396236333964363938333564343764663538353631646335353131303033356263643764373532343938303532326363373130313863346662653837643233313963663035333138363234636564613134393131636134303664656462656265646462326533306663653864346661303235373564"));$out .= writeLengthDelimitedField(24, hex2bin("7075622E4250335272446E7A67794C47442B364339507836384E7646704E574A55737A4A43347A683574394B6C38634F324830702F6B644C727157697038656376794A6F517279364B666E4D6561505932706D52706D4D575A78593D"));$out .= writeLengthDelimitedField(25, hex2bin("4D455543495143674B42776E48526D5A48314A6C5147374F544C4A7951366A555A702B43375438704C39424852574666546749674678316C32323168623763502F424B6746584E47696C49697468673738764C454957645838736D657369553D"));$out .= writeLengthDelimitedField(103, "1");$out .= writeVarintField(104, 1750960847);return $out;
}$protobuf = buildFinalMessage();
echo base64_encode($protobuf);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86517.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86517.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/86517.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

喜讯 | Mediatom斩获2025第十三届TopDigital创新营销奖「年度程序化广告平台」殊荣

6月27日&#xff0c;2025第十三届TopDigital创新营销盛典在上海圆满落幕&#xff0c;TopDigital创新营销奖获奖结果也已正式揭晓。本届TopDigital创新营销奖共有694家参展企业&#xff0c;3326件案例&#xff0c;AdMergeX旗下Mediatom媒体变现SaaS及服务平台在众多作品中脱颖而…

SQL 中 EXISTS 的原理与作用详解

平常也一直在用EXISTS 来进行逻辑判断&#xff0c;但是从来没有正经理解它&#xff0c;只知道找到有就返回True&#xff0c;没有就返回False。那么今天详细的理解一下&#xff08;主要借鉴了CSDN 其他博客文章&#xff0c;以及自己做的一个小例子&#xff09; 一、EXISTS是什么…

【Docker】解决:构建(docker build)或重新运行容器时,丢失apt-get update问题

一、解决&#xff1a;构建&#xff08;docker build&#xff09;或重新运行容器时&#xff0c;丢失apt-get update问题 在 Docker 容器中&#xff0c;每次构建&#xff08;docker build&#xff09;或重新运行容器时&#xff0c;默认情况下所有更改都会丢失&#xff0c;因为容…

流程管理系统方案成本评估报告(第一稿,复盘明确数据不准确,仅供参考哦)

​​一、成本评估框架​​ 所在制造业流程数字化转型的成本需从​​一次性投入​​与​​持续运营成本​​两个维度分析,并量化​​直接收益​​与​​间接收益​​。详细评估模型初稿: ​​二、成本构成与数据支撑​​ ​​1. 一次性投入成本​​ ​​项目​​​​费用范围…

高并发分布式锁解决方案对比与选型指南

高并发分布式锁解决方案对比与选型指南 在大规模分布式系统中&#xff0c;分布式锁是确保资源互斥访问、保证数据一致性的关键组件。针对不同业务场景&#xff0c;分布式锁的实现方案多种多样&#xff0c;各有优缺点。本文将从问题背景出发&#xff0c;对Redis原生锁/RedLock、…

全面掌握Vue 3响应式:ref自动解包、reactive对象替换及响应式丢失问题

Vue 3的响应式系统是其最核心的特性之一&#xff0c;主要通过ref和reactive这两个API来实现。本文将详细介绍这两个API的使用方法、区别以及最佳实践。 1. ref()的基本使用 ref()用于创建一个响应式的数据引用。它可以包装任何类型的值&#xff0c;包括基本类型和对象类型。 …

【科普】 AI大模型应用架构图大全

AI大模型应用架构图大全 AI大模型技术全景视图&#xff1a; AI大模型通用技术架构图 AI大模型通用技术架构图 AI大模型通用技术架构图 RAG知识库业务架构图 AI农业大模型技术架构图 AI导购大模型技术架构图 AI导购大模型技术架构图 AI大模型合规风控管理架构图 AI大模型合规管…

Educational Codeforces Round 180 (Rated for Div. 2) A-D题解

A. Race 题意 在一个数轴上&#xff0c;奖品可能出现在 x x x 点或 y y y 点&#xff0c;Alice 现在在 a a a 点&#xff0c;请问Bob是否存在一个点 b b b&#xff0c;使得无论奖品出现在 x x x 点还是 y y y 点&#xff0c;Bob都能比Alice先拿到&#xff08; ∣ b −…

IPv6配置

IPv6的基本配置 构建如下图所示的实训拓扑&#xff0c;按如下要求完成实训内容&#xff1a; &#xff08;1&#xff09;启用路由器的IPv6功能&#xff1b; &#xff08;2&#xff09;配置路由器接口的IPv6地址&#xff1b; &#xff08;3&#xff09;测试两台路由器的连通性…

flutter项目环境升级二:从Flutter2.10.5升级到3.29.3

系统:windows Android Studio:Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1 Flutter SDK: Flutter3.29.3 JDK: java 17 详细的AGP / Gradle / Kotlin / JDK版本兼容关系可以百度或者到官方文档查询,其他博主给的很详细。确认好想要的版本兼容 这位大哥有对照表…

【网站内容安全检测】之1:获取网站所有链接sitemap数据

不多BB&#xff0c;直接上代码&#xff1a; main.go package mainimport ("bufio""crypto/tls""fmt""io""net/http""net/url""os""strings""sync""time"_ "net/ht…

从零构建vue3项目(二)

Vue3项目增强配置&#xff1a;Axios封装、鉴权与代码扫描 1. Axios二次封装与拦截器配置 安装Axios npm install axios创建Axios实例 src/utils/request.js import axios from axios import { useUserStore } from /stores/user import router from /router// 创建axios实例…

哪家香港站群服务器比较好用?

面对鱼龙混杂的服务商市场&#xff0c;哪家的香港站群服务器真正稳定&#xff1f;毕竟搞站群最怕的就是服务器抽风&#xff0c;轻则掉排名&#xff0c;重则客户跑光光。今天咱就重点聊聊哪家香港站群服务器比较好用&#xff1f; 一般来说&#xff0c;在选择香港站群服务器提供…

Python的科学计算库NumPy(二)

5. 索引和切片 5.1 一维数组的索引和切片 import numpy as np# 一维数组索引和切片&#xff0c;跟python中的集合同样使用 bin_list[1,2,3,4,5,6] bin_arraynp.array(bin_list) print(bin_array[3]) print(bin_array[1:4]) print(bin_array[-2:-1])5.2 多维数组的索引 # 多维…

STM32和C++ 实现配置文件导入、导出功能

一.配置文件导出功能 // 导出流程 // 1. 客户端 → 设备:导出配置请求,例如:GetFlashData[d6fe30323454]:{ini} ,其中[]里面是设备序列号 // 2. 设备 → 客户端:配置文件元数据(总大小、块数量) // 3. 设备 → 客户端:发送块1(包含块序号和大小) // 4. 设备 → 客户端:…

HTTP 请求基础知识

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言HTTP 请求方法GETPOSTPUTDELETE其他方法 HTTP 请求结构常用请求头实际应用示例响应状态码 前言 HTTP (Hypertext Transfer Protocol) 是互联网上应用最广泛的协…

Django ORM 1. 创建模型(Model)

1. ORM介绍 什么是ORM&#xff1f; ORM&#xff0c;全称 Object-Relational Mapping&#xff08;对象关系映射&#xff09;&#xff0c;一种通过对象操作数据库的技术。 它的核心思想是&#xff1a;我们不直接写 SQL&#xff0c;而是用 Python 对象&#xff08;类/实例&…

【C/C++】C++ 编程规范:101条规则准则与最佳实践

C 编程规范&#xff1a;101条规则准则与最佳实践 引言 C 是一门强大而复杂的语言&#xff0c;能高效控制硬件&#xff0c;也能写出优雅抽象。然而&#xff0c;正因其复杂性&#xff0c;项目中若缺乏统一规范&#xff0c;极易陷入混乱、难维护、易出错的泥潭。 本文总结了 10…

柔性屏激光修屏禁区突破:新启航如何实现曲面 OLED 面板的无损修复?

一、引言 柔性 OLED 面板凭借其轻薄、可弯曲等特性&#xff0c;在智能终端、可穿戴设备等领域广泛应用。然而&#xff0c;生产过程中面板易出现缺陷&#xff0c;传统修复方法难以满足曲面 OLED 面板的无损修复需求。新启航半导体有限公司在激光修屏技术上取得突破&#xff0c;…

UI前端与数字孪生结合案例分享:智慧零售的可视化解决方案

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 一、引言&#xff1a;智慧零售的可视化变革 在数字化浪潮下&#xff0c;零售行业正从 “人货场…