protobuf是怎样实现的?首先,我们来思考最简单的情况,该怎样表示数字。
你可能会想这还不简单,统一用固定长度,比如用64个比特(8字节),这种方法可行,但问题是不论一个数字有多小,比方2,那么用这种方法表示2也需要占据64个比特(8字节):
明明只要一个字节就能表示而我们却用了8个,前面的全都是0,这也太奢侈太浪费了吧。
显然,在这里我们不能使用固定长度来表示数字,而需要使用变长方法来表示。
什么叫变长?意思是说如果数字本身比较大,那么其使用的比特位可以较多,但如果数字很小那么就应该使用较少的比特位来表示,这就叫变长,随机应变,不死板。
那怎样变长呢?
我们规定:对于每一个字节来说,第一个比特位如果是1那么表示接下来的一个比特依然要用来解释为一个数字,如果第一个比特为0,那么说明接下来的一个字节不是用来表示该数字的。
也就是说对于每个8个比特(1字节)来说,它的有效载荷是7个比特,第一个比特仅仅用来标记是否还应该把接下来的一个字节解析为数字。
根据这个规定假设来了这样一串01二进制:
1010110000000010根据规定,我们首先取出第一个字节,也就是:
10101100此时我们发现第一个比特位是1,因此我们知道接下来的一个字节也属于该数字,将当前字节的1去掉就是:
0101100然后我们看下一个字节:
00000010我们发现第一个bit为0,因此我们知道下一个字节不属于该数字了。
接下来我们将解析到的0101100(第一个字节去掉第一个比特位)以及第二个字节0000010(第二个字节去掉第一个比特位)翻转之后拼接到一起,这里之所以翻转是因为我们规定数字的高位在后。
这个过程就是:
1010110000000010 -> 10101100 | 00000010 // 解析得到两个字节 _ _ -> 0101100 | 0000010 // 各自去掉最高位 -> 0000010 | 0101100 // 两个字节翻转顺序 0000010 + 0101100-> 100101100 // 拼接最后我们得到了100101100,这一串二进制表示数字300。
这种数字的变长表示方法在protobuf中被称之为varint。
因此在这种表示方法下,如果数字较大,那么使用的比特就多,如果数字较小那么使用比特就少,聪明吧。
有的同学看到这里可能会问题,刚才讲解的方法只能表示无符号数字,那么有符号数字该怎么表示呢?比如-2该怎么表示?
有符号数的表示按照刚才变长编码的思想,-2147483646使用的比特位应该比-2要少。
然而我们知道在计算机世界中负数使用补码表示的,也就是说最高位(最左侧的比特位)一定是1,假设我们使用64位来表示数字,那么如果我们依然用补码来表示数字的话那么无论这个负数有多大还是多小都需要占据10个字节的空间。
为什么是10个字节呢?
不要忘了varint每个字节的有效负荷是7个比特,那么对于需要64位表示的数字来说就需要64/7向上取整也就是10个字节来表示。
这显然不能满足我们对数字变长存储的要求。
该怎么解决这个问题呢?
既然无符号数字可以方便的进行变长编码,那么我们将有符号数字映射称为无符号数字不就可以了 ,这就是所谓的zigzag编码,是不是很聪明,就像这样:
原始信息 编码后0 0 -1 1 1 2-2 32 4-3 53 6... ...2147483647 4294967294-2147483648 4294967295这样我们就可以将有符号数字转为无符号数字,接收方接收到该数据后再恢复出有符号数字。
现在数字的问题彻底解决了,但这仅仅是万里长征第一步。
iPhone8什么时候上市?iPhone8最新消息:iPhone8、iPhone7S、iPhone7SPlus配置、价格对比,iPhone8有何优势?
分布式电压接线异常在线监测技术实现
YouTube 宕机期间,谷歌损失了约 170 万美元
中国智慧城市建设现状及问题全解析
微流控技术中使用的不同类型的水凝胶
Google二进制编解码技术之Protobuf 2
华为手机销售情况峰回路转 国内高端供应链有望利好
FP7195转模拟无频闪调光“频闪仪” 测试
面对人工智能浪潮 促进与实体经济深度融合,形成新增长点的解析
邓中翰:我认为人工智能最终会造福于全人类
简单易制的STC单片机ISP下载线,ISP PROGRAMMER
芯片价格战日趋白热化集成电路产业未来路在何方?
无线开关量模块使用注意事项
安规电容的组成及选择介绍!
x射线测厚仪的组成_x射线测厚仪主要技术参数
Stanley Robotics推出“代客泊车机器人”,于法国里昂机场开测
人工智能技术将与传统的自动化、机器人技术融合,重塑制造业
企校联合、科技点燃梦想——渭南市三贤中学走进西安国盛激光
智慧工厂能源在线监控平台开发工业能源管控系统开发
西门子PLC模拟量输入模块时接收到变动很大的不稳定的值?