`
ordinary
  • 浏览: 77580 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Base 128 Varints

阅读更多

 Google Protobuf里面提出了“Base 128 Varints”编码,这是一种变字节长度的编码,官方描述为:varints是用一个或多个字节序列化整形的一种方法。我理解要点有三个(1)操作是序列化(2)操作对象是整形(3)变长编码。重点是最后一点,他是如何编码的呢?

       (1)除了最后一个字节,varint中的每个字节的最高位设为1,表示后面还有字节出现

       (2)每个字节的低7位看成是一个组(group),这个组和他相邻的下一个7位组共同存储某个整形的“组合表示”,最低有效组在前面。

    上面的定义可能比较生硬,我没看具体例子之前,也没搞明白,我们来看http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/encoding.html#varints中的例子:

        (1)一个字节。下面只有一个字节,所以最高位是0,表示十进制1

            0000 0001

        (2)两个字节。

            1010 1100 0000 0010

        由于第一个字节后面还有一个字节,所以第一个字节的最高位设置为1,表示后面还有后继字节,第二个字节的最高位为0。去掉每个字节的最高位,我们对两个字节进行分组。第一个7位组:0101100,第二个7位组:0000010,组合起来就是:0101100 0000010,由于最低有效组在前面,所以两个7位组进行调换,结果为:0000010  0101100,中间的空格是为了大家区分,去掉前面的0,也就是:100101100,十进制为1*2^8 + 1*2^5 + 1*2^3 + 1*2^2 = 256 + 32 + 8 + 4 = 300。

       (3)三个字节。我们换种方式,给定某个整形,要求写出他的varint表示,这里当然是落在需要3个字节表示的整形。16380可以吗?不可以!因为16380 < 2^14,所以2个字节足以,我们就以27491为例,27491的二进制表示为:

                     0110 1011 0110 0011

        注意这里是高字节之前,低字节在后,和varint的编码规则相反,首先按照7位一组划分为:0000001 1010110  1100011然后反转为:1100011 1010110  0000001,最后将末尾的7位组前面补0组成一个字节,两个7位组都补1分别组成一个字节:

                     11100011 11010110  00000001

       (4)更多字节。聪明的你可能发现,varint编码中4个字节最大表示的数为2^28,非常正确,同时说明了天下没有免费的午餐,有得有失。Protobuf引入了fixed32解决这个问题的,如果某个字段经常大于2^28,应当优选fixed32,他是固定长度为32位的。

     三.String和bytes

     string和bytes的表示形式一致,都是“长度+值”,其中长度采用varint编码,值为字符序列或者二进制码流

分享到:
评论
1 楼 yhxf_ie 2017-03-24  
             通俗易懂

相关推荐

    Protocol Buffers 入门应用

    NULL 博文链接:https://lfl2011.iteye.com/blog/2136272

    Protocol Buffers协议编码规则

    它是以Base 128 Varints编码基础, varints是一种将一个整数序列化为一个或者多个Bytes的方法,越小的整数,使用的Bytes越少。 基本规则 1.每个Byte的最高位(msb)是标志位,如果该位为1,表示该Byte后面还有其它Byte...

    Python库 | base128-0.1.1-py3-none-any.whl

    资源分类:Python库 所属语言:Python 使用前提:需要解压 资源全名:base128-0.1.1-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    这个是base的解码工具

    有base的乱码,他可以解决 http://u.115.com/file/clnern84# Base解码工具.exe

    Base64 编码 解码器 V1.6

    这是一个很好的Base64编-解码工具.转换很方便,支持中文,支持UTF-8,Unicode编码,可对对图片数据进行解码。  Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,可以参见RFC2045~RFC2049,上面有MIME...

    AES-128-CBC加密Base64编码Demo

    AES-128-CBC加密Base64编码Demo,亲测有效。而且 直接引入了BASE 64编码类 非常方便。不过只有加密算法

    nodejs的base64和aes-128-ecb加密.rar

    nodejs的base64和aes-128-ecb加密.rar

    base16 base32 base64 C语言代码

    base16,base32,base64C语言实现代码,高效率运行,非常实用。

    Base64.dll(Base64编解码,附VB示例)

    Base64编码和解码库,支持API调用和COM调用,输入参数支持VB的字节数组Byte(),输出支持VB的字节数组Byte()和...Public Declare Sub DecodeFromVBStringEx Lib "Base64" (ByRef Dest() As Byte, ByRef Src As String)

    sun.misc.BASE64Decoder(Android Base64Jar包以及Java源代码)

    sun.misc.BASE64Decoder 其中包括 Android Base64Jar包 以及Java源代码 sun.misc.BASE64Decoder 其中包括 Android Base64Jar包 以及Java源代码 sun.misc.BASE64Decoder 其中包括 Android Base64Jar包 以及...

    JS 版本的base64函数实现(base64encode,base64decode)

    用js实现的base64encode,base64decode函数. 包括: function base64encode(str) { function base64decode(str) { function utf16to8(str) { function utf8to16(str) { function doit() {

    aes128base64_aes128_

    基于单片机 C 语言通用AES128加密算法

    ctf base全家桶递归解密

    ctf base全家桶递归解密,只要是常见base(base16、base32、base58、base85、base91、base92、base100)系加密,不管加多少层都能解出来

    pb-base64.zip

    pb10调用base64.dll,实现将图片转换成base64编码,将base64编码转换成图片 函数声明 function long GetFileEncode64(ref string filename, ref string encode64)library "base64" alias for "GetFileEncode64;...

    labview 图片缩放 base64编码base64解码

    labview 图片缩放 base64编码base64解码

    js的base64(base64.js)

    js的base64(base64.js)

    js的base64和base32加密函数

    js的base64和base32加密函数 ajax通过get方式传递中文参数特殊符号的参数避免乱码终极解决方案.

    sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用已解决

    最近项目实验发现导入工具程序后项目有错,查看发现sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用,找不到相应的类。 二、原因分析 冲浪后发现JDK中的lib\tools.jar和JRE中的lib\rt.jar已从Java SE 9中...

    c# 用Base64实现文件上传

    Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,它是一种基于64个可打印字符来表示二进制数据的方法。  使用base64进行文件上传的具体流程是:前台使用js将文件转换为base64格式,后台通过高级编程语言...

Global site tag (gtag.js) - Google Analytics