protobuf varint编解码实现

Varint+ZigZag编码和解码 如何对一个字节或多个字节的数据序列化并压缩 阅读详情

varint:int数字用变长字节数组表示。

package com.ls.hfvj;

import java.util.Arrays;

/**
 * varint:把整数用变长字节数组表示,每个int用1-5个byte表示。一个字节内,低7位是有效数据位,第8位是标识位,1表示有后续字节,0则表示该整数的结束没有后续字节。
 * 当整数是小正数时,得到的字节序列明显比较小一些。
 * 编码:每次取7位,或上符号位。 
 * 解码:每次从一个字节中取低7位进行位或
 * @author lihao
 */
public class VarintEncode {
	/**
	 * 对一个整数进行varint编码,返回编码后的字节序列 一个字节有8位,用最高位表示下一个字节是否连续
	 */
	public static byte[] encode(int val) {
		byte[] data = new byte[computeLength(val)];
		for (int i = 0; i < data.length - 1; i++) {
			data[i] = (byte) ((val & 0x7F) | 0x80);// 用位或运行填上一个高位1,大类型向小类型强转只保留低位,高位丢失
			val = val >>> 7;
		}
		data[data.length - 1] = (byte) (val);
		return data;
	}

	/**
	 * 从一个整数的varint序列还原该数 4*7=28,若有5个字节,则第五个字节只有后4位是属于原数字的;//notice
	 */
	public static int decode0(byte[] data) {
		int val = 0;
		int i = data.length - 1;
		if (data.length == 5) {
			val = val | (data[i] & 0x0F);// 只要后四位
			i -= 1;
		}
		while (i >= 0) {
			val = val << 7;
			val = val | (data[i] & 0x7F);
			i--;
		}
		return val;
	}

	/**
	 * 把int转为varint编码需要的字节数 ,每次无符号右移7位,直到为0。返回值为1-5
	 */
	public static int computeLength(int val) {
		if (val == 0) {
			return 1;
		}
		int length = 0;
		while (val != 0) {
			val = val >>> 7;
			length++;
		}
		return length;
	}

	public static void main(String[] args) {
		byte[] data = encode(300);
		System.out.println(Arrays.toString(data));
		System.out.println(decode0(data));
	}
}

 

Protobuf性能优化指南:如何避免序列化和反序列化中的常见陷阱 本文深入探讨了Protobuf在序列化和反序列化过程中的性能优化策略,帮助开发者避免常见陷阱。通过优化消息结构设计、编码技巧、内存管理和并发处理,显著提升序列化吞吐量并降低内存消耗。特别适合处理高QPS微服务调用和大规模数据持久化的场景。 阅读详情

相关推荐

94.Android系统源码-nanopb 实战 - Android 嵌入式 Protocol Buffers 零内存分配实现

摘要:nanopb 是一个超轻量级 Protocol Buffers 实现,专为嵌入式系统设计。核心特点包括:代码体积仅几KB(3个核心C文件约2500行)、零动态内存分配(默认静态预分配)、表驱动架构(通过pb_field_t静态描述表遍历结构体字段)、与标准protobuf二进制兼容。在Android中被集成到蓝牙等内存敏感组件中(libprotobuf-c-nano)。技术亮点包括:字段迭代器、流式I/O抽象、变长整数编码、函数指针分派表等,实现了在极低资源环境下运行protobuf序列化的能力。

保持专注,保持热爱 17

Protobuf 介绍与实战50:Varint 正数编码过程、负数编码过程、解码过程介绍

1  go grpc-go 相关技术专栏 总入口 2  Protobuf介绍与实战 图文专栏 文章目录 1、Varint编码方式,适合的场景? 适合对正数进行编码 不适合负数。 2、正数的Varint编码过程,如下(举个例子说明) 假设传输的是1029,类型为int32 int32类型的1029,如果使用Varint编码的话, 在64位操作系统下,需要使用4个字节传输,其中2个字节是无需的; 使用Varint编码后,只需要2个字节传输即可。 下面是1029为uint32类型时的情况: 3、负数的Vari

码二哥的技术池 1317

Rust中的SIMD加速varint编码器和解码器-Rust开发

varint-simd是用Rust编写的快速SIMD加速的可变长度整数编码器和解码器。 它旨在用于协议缓冲区(protobuf),Apache Avro和类似的序列化格式的实现中。 varint-simd varint-simd是用Rust编写的快速SIMD加速的可变长度整数编码器和解码器。 它旨在用于协议缓冲区(protobuf),Apache Avro和类似的序列化格式的实现中。 该库当前针对支持SSSE3(Intel Core / AMD Bulldozer或更高版本)的x86_64处理器,对支持POPCNT和LZCNT的处理器进行了可选的优化,以及对支持AVX2的处理器进行了有限的自动矢量化。 重要用法:

varint原理 - 正数的编码和解码

varint原理

papaya的博客 2052

Varint+ZigZag解码 ZigZag编码

实现Varint + ZigZag的编解码过程,里面有我自己对Vint编解码实现的算法 ,VInt编码为Varint编码和ZigZag编码的结合,为一种将64位二进制编码的有符号整型编码在最多10字节中的编码方式。Varint编码为一种将64位二进制编码的无符号整型根据其大小用不同长度字节进行编码的编码方式。其编码特点为数字越小所占用的字节数越少。每个字节的低7位用来表示数字,最高位有特殊的含义:如果该位为 1,表示后续的一个字节也是该数字的一部分;如果该位为 0,则该字节为该数字的最后一个字节。因此小于 128 的数字都可以用一个字节表示。大于 128 的数字,会用两个或两个以上的字节编码。ZigZag编码是为了配合Varint来使用的一种为有符号整型数定义的编码。ZigZag的原理是按照绝对值大小来重新解析二进制。VInt的编码实际上是将64位整数的有符号编码首先使用ZigZag转换后,再用Varint进行的编码。VInt的编码与Google Protocol Buffer中wire type中的sint64的编码相同。

软件工程案例教程·韩万江【课后习题】

!!!!

weixin_57858263的博客 6419

详解varint编码原理

什么是Varint编码 Varint是一种使用一个或多个字节序列化整数的方法,会把整数编码为变长字节。对于32位整型数据经过Varint编码后需要1~5个字节,小的数字使用1个byte,大的数字使用5个bytes。64位整型数据编码后占用1~10个字节。在实际场景中小数字的使用率远远多于大数字,因此通过Varint编码对于大部分场...

kevin_tech的博客,微信搜「网管叨bi叨」 1740

【Unity】入门教程第一期-下载安装Unity编辑器(下)

讲解如何在Unity Hub中下载Unity编辑器以及IED环境

Xiaoxin的博客 2040

【Protobuf】Protobuf的编解码规则详解

在很多很多时候被问起,为什么选择protobuf?最先被想起的回答的就是体积小、解析快。那相比较于json、XML,为什么protobuf能够做到又小又快呢? 归其原因,这与它的编解码方式有很大的关系。本文将走进protobuf的深层原理来进行剖析。 实例 本文针对实际的例子,来对protobuf的编解码方式进行详细讲解。其中,.proto文件定义如下: syntax = "proto2"; ...

Yngz_Miao的博客 1万+

从零到一:AIGC+Unity3D打造动态天空盒的实战指南

本文详细介绍了如何利用AIGC技术结合Unity3D打造动态天空盒的实战指南。通过AIGC生成360全景图,再集成到Unity3D中,实现高效、多样化的天空盒效果。文章涵盖了从AIGC全景图生成、工作流搭建到Unity场景集成的完整流程,并提供了代码示例和优化建议,帮助开发者快速掌握这一技术。

weixin_29021291的博客 603

Cadence 设计实践笔记-小哥allegro 2层板笔记

规范建立文件夹本章节主要跟着B站PCB入门首选视频-小哥Cadence Allegro 2层板视频,结合自己的实践一步步完成一个完整的PCB板的设计。规范建立文件夹建立八个文件夹我使用的Cadence 17.4 有些差异原理图绘制原图绘制首先要熟悉原理图工作原理工作原理下面是这个项目的原理图重点关注电源新建原理图库打开Cadence 软件创建项目新建工程 File ==========》Project我这里选择了Enable PSPice 试试能不能仿真,新建项目如下。

我的专栏 1479

probuf与netty的编解码

之前直接用框架中的编解码,没有设计具体代码,现在要和C交互,需要设计具体的编解码实现, 其中 new ProtobufVarint32LengthFieldPrepender(), new ProtobufEncoder(), new ProtobufVarint32FrameDecoder(), new Protobuf.ProtobufDecoder(Frame.Parser) ...

Henry_Wu001的专栏 279

Unity 面试篇|(三)设计模式篇 【全面总结 | 持续更新 | 建议收藏】

设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的总结。设计模式与方法或库的使用方式不同, 你很难直接在自己的程序中套用某个设计模式。模式并不是一段特定的代码, 而是解决特定问题的一般性概念。你可以根据模式来实现符合自己程序实际所需的解决方案。常常会混淆模式和算法, 因为两者在概念上都是已知特定问题的典型解决方案。但算法总是明确定义达成特定目标所需的一系列步骤, 而模式则是对解决方案的更高层次描述。同一模式在两个不同程序中的实现代码可能会不一样。单例模式。

游戏开发小Y的博客 12万+

深入解析Protobuf编码:从Varint到ZigZag的优化实践

本文深入解析了Protobuf的核心编码机制,重点阐述了Varint变长编码如何高效压缩小整数,以及ZigZag编码如何巧妙解决负数存储空间过大的难题。通过TLV结构、实战手算示例及Packed Repeated等高级优化实践,揭示了Protobuf实现极致空间效率与解析速度的设计哲学,为协议设计与性能优化提供了关键指导。

h0i1j2k3l的博客 730

rk3588上适配wifi模组aic8800

记录一下在rk3588上调试aic8800,调试分为Debian11以及Android12两个平台,这里主要是讲过程以及修改的过程,以补丁的形式来提供解决方法。在Debian11下主要通过配置设备树、编译驱动并自动加载固件完成调试,详细介绍了设备树修改、驱动编译脚本调整和驱动加载流程。

m0_60805802的博客 1003

自适应控制 (Adaptive Control) 算法详解及案例分析

自适应控制是一种能够在线调整控制器参数以适应系统动态变化的控制方法。其核心思想是通过实时估计系统参数或调整控制器参数,使系统在不确定性或动态变化的环境中仍能保持稳定性和性能。

闲人编程的博客 4084

神奇的Google二进制编解码技术:Protobuf

这个问题可不像看上去的那样简单,因为client进程和server进程运行在不同的机器上,这些机器可能运行在不同的处理器平台、可能运行在不同的操作系统、可能是由不同的编程语言编写的,server要怎样才能识别出client发送的是什么数据呢?可见,同样一串二进制在不同的“上下文/协议”下有完全不一样的解读, 这也是为什么计算机明明只认知0和1但是却能处理非常复杂任务的根本原因,因为一切都可以编码为0和1,同样的我们也可以从0和1中解析出我们想要的信息,这就是所谓的编解码技术。

m0_73257876的博客 1117

三维重建/SLAM笔记_最佳学习路线/攻略

本文目的 学习三维重建,需要不少知识,而知识之间又存在不同的依赖关系,为了后来人能少走弯路,也为了对自己的知识框架系统总结,特记录自己的学习路线。 学习心得 关于读书,了解基础知识是一方面,产生疑问也是一方面,为以后知道学习什么留下印象; 一回生,二回熟,看不懂时,大多是因为先验知识不够,没关系,多查多想,总会搞懂的。 学习路线 1.计算机图形学基础(OpenGL基础版)(徐文鹏 清...

惊鸿一博 3291

ClawHub GitHub 导入全解析:从自有公开仓库一键发布 Skill

GitHub 导入是 ClawHub 为 Skill/Plugin 作者提供的一条核心发布通道:登录用户可以从自己名下的公开 GitHub 仓库中自动检测 `SKILL.md` 或遗留格式 `skills.md`,经选择性文件勾选、预览与发布后,把仓库内容发布为 ClawHub 上的 Skill,并在每个版本上持久化 GitHub 溯源信息。本文将基于仓库中的功能规格文档 [specs/githu

gitblog_00007的博客 337

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

技术深度解析:lua-protobuf如何实现纯Lua的Protocol Buffers支持

lua-protobuf是一个为Lua语言提供Google Protocol Buffers完整支持的C模块与纯Lua编译器实现。该项目通过独特的架构设计,在保持高性能的同时实现了对protobuf协议版本2和3的全面支持,为Lua生态系统填补了结构化数据序列化的重要空白。其核心技术创新在于将C语言的高性能编解码能力与纯Lua实现的协议编译器相结合,提供了零外部依赖的完整解决方案。 ## 技术架

gitblog_00896的博客 218

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

多协议转换:用 Go 标准库手写 gRPC 翻译网关

这次实践表明,协议网关本质是数据包重组和转发的代理服务。其操作与手写帧头和二进制拼装无异。生产环境需用成熟框架保障效率,但手动实现有助于深入理解技术。

m0_50889382的博客 4214

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

[Protobuf] 二进制编码 | Varint & Zigzag(-) | vs json

当数值普遍小于 2^28 时,选择变长编码。 sint32 和 sint64:结合 VarInt (MSB 最高位标记) 和 ZigZag 编码,适合负数场景。

No Game No Life 1588

Protobuf底层编码深度拆解:Varint压缩、嵌套消息序列化、字段兼容,手写极简Protobuf编解码器

文章摘要 本文深入解析Protobuf底层编码机制,重点剖析Varint压缩、TLV结构和字段兼容设计。与JSON等自描述格式不同,Protobuf采用契约化编码,通过.proto文件预先约定数据结构,二进制流中仅存储紧凑的Tag-Length-Value三元组。核心创新包括:1) Varint变长整数编码,利用MSB位实现1-10字节自适应压缩;2) TLV通用存储结构,将字段编号与线类型打包成Tag;3) 小端序字节排列优化解码效率。实测显示Protobuf体积比JSON小60%以上,吞吐量提升5.6倍

网络工程师|十多年企业级运维实战|精通 ‌BGP、OSPF、VLAN、SDN、MPLS、ACL、NetFlow、SNMP、 511

protobuf编解码研究

背景 一.优势 1、json: 一般的web项目中,最流行的主要还是json。因为浏览器对于json数据支持非常好,有很多内建的函数支持。 2、xml: 在webservice中应用最为广泛,但是相比于json,它的数据更加冗余,因为需要成对的闭合标签。json使用了键值对的方式,不仅压缩了一定的数据空间,同时也具有可读性。 3、protobuf:是后起之秀,是谷歌开源的一种数据格式,适合高性能,对响应速度有要求的数据传输场景。因为profobuf是二进制数据格式,需要编码和解码。数据本身不具有可读

ikunkun博客 1497

protobuf int类型变长存储 varint32 和 varint64

VarInt32 编码 VarInt32 (vary int 32),即:长度可变的 32 为整型类型。一般来说,int 类型的长度固定为 32 字节。但 VarInt32 类型的数据长度是不固定的,VarInt32 中每个字节的最高位有特殊的含义。如果最高位为 1 代表下一个字节也是该数字的一部分。因此,表示一个整型数字最少用 1 个字节,最多用 5 个字节表示。如果某个系统中大部分数字需要 >= 4 字节才能表示,那其实并不适合用 VarInt32 来编码。下面以一个例子解释 VarInt32

TH_NUM的博客 2275
上一篇: 网络编程基础
下一篇: base64编码实现
away_lit
博客等级 码龄11年 5粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值