Varint和Zigzag

Varint和ZigzagVarint就是一种对数字进行编码的方法,编码后二进制数据是不定长的,数值越小的数字使用的字节数越少。例如对于int32_t,采用Varint编码后需要1~5个字节,小的数据使用1个字节,大的数字使用5个字节。基于实际场景中小数字的使用远远多于大数字,因此通过Varint编码对…

Varint就是一种对数字进行编码的方法,编码后二进制数据是不定长的,数值越小的数字使用的字节数越少。例如对于int32_t,采用Varint编码后需要1~5个字节,小的数据使用1个字节,大的数字使用5个字节。基于实际场景中小数字的使用远远多于大数字,因此通过Varint编码对于大部分场景可以起到一个压缩的效果。

无符号

Varint中的每个字节的最高位bit有特殊的含义,如果该位为1,表示后续的字节也是该数字的一部分,如果该位为0,则结束。其他的7个bit都用来表示数字。因此小于128的数字都可以用一个字节表示。大于128的数字,会用两个字节。

例如整数1的表示,仅需一个字节:

0000 0001

例如300的表示,需要四个字节:

1010 1100 0000 0010

Varint和Zigzag

def encode(num):
    buf = ""
    while True:
        n = num & 0x7f
        num >>= 7
        if num != 0:
        	n |= 0x80
            buf += chr(n)
        else:
            buf += chr(n)
            break
    return buf

def decode(buf):
    num = 0
    shift = 0
    i = 0
    while True:
        n = ord(buf[i])
        i += 1
        num |= (n & 0x7f) << shift
        shift += 7
        if not (n & 0x80):
            break
    return num

有符号

在有符号的情况下,需要使用有符号数到无符号数的映射,Zigzag编码。

详细的映射表如下:

Signed Original Encoded As
0 0
-1 1
1 2
-2 3
2 4
2147483647 4294967294
-2147483647 4294967295
inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
  // Note: the right-shift must be arithmetic
  return (n << 1) ^ (n >> 31);
}

inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
  return (n >> 1) ^ -static_cast<int32>(n & 1);
}

inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
  // Note: the right-shift must be arithmetic
  return (n << 1) ^ (n >> 63);
}

inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
  return (n >> 1) ^ -static_cast<int64>(n & 1);
}

通过Zigzag编码后,就可以对负数进行varint编码了。

但是,如何发现这种映射方法,目前还没有明白,希望大佬们可以在评论区留言解惑。

www.cnblogs.com/jacksu-tenc…

izualzhy.cn/protobuf-en…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13803.html

(0)

相关推荐

  • hadoop源码_hdfs启动流程_2_DataNode「建议收藏」

    hadoop源码_hdfs启动流程_2_DataNode「建议收藏」执行start-dfs.sh脚本后,集群是如何启动的? 本文阅读并注释了start-dfs脚本,以及datanode的启动主要流程流程源码。 DataNode 启动流程 脚本代码分析 start-df

    2023-04-18
    158
  • Python的字符串计数方法应用与示例

    Python的字符串计数方法应用与示例在Python中,字符串计数是一个非常常见的操作。Python内置的字符串方法和模块中提供了各种字符串计数的方法,包括计算字符串中某个字符出现的次数、计算一个字符串在另一个字符串中出现的次数、计算字符串中某个子串出现的次数等。

    2024-02-05
    101
  • Python中查看List长度的方法

    Python中查看List长度的方法在Python中,使用List非常方便,它可以存储多个元素,且元素类型可以不同。如果我们需要知道一个List中元素的个数,就需要查看它的长度。本文将从多个角度介绍Python中查看List长度的方法。

    2024-04-24
    71
  • 达梦数据库间隔分区应用(interval)

    达梦数据库间隔分区应用(interval)在达梦中我们也可以使用间隔分区,需要注意的是达梦中的间隔分区使用有以下限制

    2023-03-24
    180
  • 依赖注入怎么理解_面试官的问题回答不上来怎么办

    依赖注入怎么理解_面试官的问题回答不上来怎么办IOC: Inversion Of Control 控制反转DI: Dependency Injection 依赖注入1.控制反转 Invers

    2023-07-05
    139
  • oracle数据库启动的三个阶段_oracle 启动

    oracle数据库启动的三个阶段_oracle 启动1、查看监听 lsnrctl status;lsnrctl start;lsnrctl stop; 2、关闭数据库 shutdown immediate; 3、启动数据库(nomount,mount…

    2023-02-27
    142
  • Python Mac安装教程

    Python Mac安装教程Python是一门跨平台的高级编程语言,其具有易读易写、可扩展性强、可移植性好等优点,是目前最受欢迎的编程语言之一。在Mac OS X操作系统中,Python已经预装了Python 2.x版本,但如果需要使用Python 3.x版本,则需要自行安装。本教程将介绍如何在Mac上安装Python 3.x版本。

    2024-05-15
    68
  • nmap渗透测试指南 pdf_nmap使用方法

    nmap渗透测试指南 pdf_nmap使用方法Nmap是一款网络扫描和主机检测的非常有用的工具。 Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器。它可以适用

    2023-07-04
    119

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注