varint编码

什么是varint编码

Varint是一种使用一个或多个字节序列化整数的方法,会把整数编码为变长字节。

对于32位整型数据经过Varint编码后需要1~5个字节,小的数字使用1个byte,大的数字使用5个bytes。

64位整型数据编码后占用1~10个字节。在实际场景中小数字的使用率远远多于大数字,因此通过Varint编码对于大部分场景都可以起到很好的压缩效果。

编码原理

varint编码中的每个字节都设置了最高有效位(most significant bit - msb)–msb为1则表明后面的字节还是属于当前数据的,如果是0那么这是当前数据的最后一个字节数据。每个字节的低7位用于以7位为一组存储数字的二进制补码表示,使用小端字节序存储。

为啥使用小端字节序存储?

从原理出发:varint 编码的意义是使较小的数使用较少的编码(二进制字节流前导0较多),去除前导 0;假设使用大端字节序存储,前导 0 不会删除。

zigzag 编码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @author N3verL4nd* @date 2022/2/16*/
public class Test2 {/*** int to varint 编码** @param n* @return*/public static byte[] IntToVarInt(int n) {List<Byte> list = new ArrayList<>();while (true) {if ((n & ~0x7F) == 0) {list.add((byte) n);break;} else {list.add((byte) ((n & 0x7F) | 0x80));n >>>= 7;}}byte[] bytes = new byte[list.size()];for (int i = 0; i < bytes.length; i++) {bytes[i] = list.get(i);}return bytes;}public static void main(String[] args) {for (int i = Integer.MIN_VALUE; i <= 0; i++) {System.out.println(IntToVarInt(i).length);}}
}

32 位负数使用 varint 编码恒定占用 5 个字节;64 位负数使用 varint 编码恒定占用 10 个字节。

Zigzag 编码的大致思想是首先对负数做一次变换, 将其映射为一个正数, 变换以后便可以使用 Varints 编码进行压缩, 这里关键的一点在于变换的算法, 首先算法必须是可逆的, 即可以根据变换后的值计算出原始值, 否则就无法解码, 同时要求变换算法要尽可能简单, 以避免影响 Protobuf 编码、解码的速度, 我们假设 n 是一个 32 位类型的数字, 则 Zigzag 编码的计算方式为

(n << 1) ^ (n >> 31)

要注意这里左边是逻辑移位, 右边是算术移位, 右边的含义实际是得到一个全 1 (对于负数) 或全 0 (对于正数)的比特序列。

zigzag 编码的目的是将绝对者较小的负数转为正整数。

package study.proto;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @author N3verL4nd* @date 2022/2/16*/
public class Test2 {/*** int to varint 编码** @param n* @return*/public static byte[] IntToVarInt(int n) {List<Byte> list = new ArrayList<>();while (true) {if ((n & ~0x7F) == 0) {list.add((byte) n);break;} else {list.add((byte) ((n & 0x7F) | 0x80));n >>>= 7;}}byte[] bytes = new byte[list.size()];for (int i = 0; i < bytes.length; i++) {bytes[i] = list.get(i);}return bytes;}/*** long to zigZag 编码** @param l* @return*/public static long longToZigzag(long l) {return (l << 1) ^ (l >> 63);}/*** 对于负数,n >> 1 全为 1* 对于正数,n >> 1 全为 0** @param n* @return*/public static int intToZigZag(int n) {return (n << 1) ^ (n >> 31);}public static int zigZagToInt(int n) {return (n >>> 1) ^ -(n & 1);}public static void main(String[] args) {System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));System.out.println(intToZigZag(-1));System.out.println(intToZigZag(Integer.MIN_VALUE));System.out.println(Arrays.toString(IntToVarInt(intToZigZag(Integer.MIN_VALUE))));System.out.println(Arrays.toString(IntToVarInt(-1)));System.out.println(Arrays.toString(IntToVarInt(Integer.MIN_VALUE)));}
}

https://blog.csdn.net/carson_ho/article/details/70568606

https://halfrost.com/protobuf_encode/

varint zigzag 编码学习相关推荐

  1. Varint+ZigZag编码和解码

    前言 经常接触数据通信的朋友应该对数据的"序列化"和"反序列化"有所了解,用与可以跨平台存储,和进行网络传输. 序列化:把对象转化为可传输的字节序列过程称为序列 ...

  2. jpeg编码学习笔记

    jpeg编码学习笔记 各种图片格式目的是在网络传输和存储的时候使用更少的字节,即起到压缩的作用.在图片格式解码后,无论图片的格式,图片数据都是像素数组. 本文将尝试通过JPEG这种图片编码格式的学习, ...

  3. ZigZag 与 反ZigZag编码

    2019独角兽企业重金招聘Python工程师标准>>> 如图所示,ZigZag编码就是将 8 x 8 的矩阵块按照箭头运动方向重新排列 在 Jpeg 图像编码中主要用于 RLE (R ...

  4. 硬编码学习笔记(二)—— 经典变长指令

    硬编码学习笔记(二)-- 经典变长指令 前言 指令结构 符号说明 寻址符号 操作数符号 上标符号 One-Byte Opcode Map 变长指令 ModR/M 例:0x88 例:0x89 例:0x8 ...

  5. 硬编码学习笔记(一)—— 经典定长指令

    硬编码学习笔记(一)-- 经典定长指令 前言 指令结构 符号说明 寻址符号 操作数符号 上标符号 One-Byte Opcode Map 经典定长指令:修改寄存器 0x40~0x47 0x48~0x4 ...

  6. 【视频编码学习】——SAD和SATD

    视频编码学习--SAD和SATD 一.常用误差定义 SAD(Sum of Absolute Difference)=SAE(Sum of Absolute Error)即绝对误差和 SATD(Sum ...

  7. 深度学习系列(三):简单网络的自编码学习

    本节将研究深度学习网络权值设计的重要思想之一:自编码思想,在正式介绍之前先以一个简单的介绍一篇,一层隐含层网络的自编码学习问题. 什么是自编码?所谓自编码就是自己给自己编码,再简单点就是令输出等于输入 ...

  8. 1029mysql_今日编码学习(1029)

    下图是前不久10月24日,阿里技术公众号的一个小谜题.大家可以尝试做一做. 1024挑战书 ..-./----./-..../...--/..-/..-./----./.----/-..-/-..-/ ...

  9. Ruby:字符集和编码学习总结

    背景 Ruby直到1.9版本才很好的支持了多字节编码,本文简单总结了今天学习的关于Ruby编码方面的知识. 字符串可以使用不同的编码 在.NET中字符串的编码是一致的,Ruby允许字符串有不同的编码, ...

最新文章

  1. 解决module ‘numpy‘ has no attribute ‘array‘问题
  2. 计算机里硬盘图标,计算机中在硬盘图标下面有个其他里PPS图标肿么删?
  3. 数据结构—二叉树BinaryTree
  4. IBASE handle free after save - buffer table cleared
  5. flask查询mysql数据展示_flask下直接展示mysql数据库 字段
  6. python用schedule模块实现定时任务
  7. 软件工程复习提纲——第十一章
  8. python在物联网中的应用_在物联网中应用机器学习
  9. php+mysql 图书管理系统源码AfireHong
  10. 面试前hr加了微信,面试后是否可以向hr询问面试结果?
  11. 整数进制转换技巧以及相关算法题讲解(简洁易懂)
  12. 21个终身受用的顶级思维
  13. 运动会加油稿计算机学院150字,学校运动会加油稿150字5篇
  14. 关于华硕笔记本重装系统后引起的一些列问题的解决方案
  15. (动归三剑客)打家劫舍 (动归三剑客)
  16. 【Linux系统开发】x210开发板根目录文件系统构建
  17. 东京商城注册页面使用的正则表达式......
  18. 简单的交换排序法(选择排序)。
  19. 采集网站服务器配置,搭建数据采集云服务器源码
  20. Apple iPad:过渡设备还是平板电脑?

热门文章

  1. Centos7 双网卡配置
  2. OpenCV 2.图像入门:读取、显示、保存
  3. imu matlab,IMU姿态解算matlab
  4. python泊松分布_常见概率分布的Python实现
  5. MATLAB用rbf拟合sinx,为什么径向基(RBF)网络拟合度很差呢?
  6. 什么是MapReduce(入门篇)
  7. linux 定时开关机
  8. PTA 7-20 学分差
  9. 软件架构设计最佳实践(课程大纲)
  10. SQL中NVL()用法