每天进步一点点:Varint编码

in #cn4 years ago

在处理memo的时候,发现steem-python 以及 beem 等,都是假定编码后的字符串长度值可以存储在一个字节内,这样memo的长度只能限制在255个字节以内了。


(图源 :pixabay)

memo 长度问题

比如steem-python中处理message的部分代码如下:

image.png

那么memo到底支持多长的内容呢?在微信群中提出这个问题后,@abit 指出memo可以支持任意长度(受限于区块大小,RC等)

那么支持任意长度的话,长度信息是如何打包message当中呢?固定字节数我会取,不固定的咋办呢?在群里提出这个问题后,@abit 指出,长度的编码使用varint。

再回头看我截取的那段steem-python代码,注释中已经提到了varint,但是被我无视了,这回知道了方向,就好办了。

varint编码

简单了解了一下varint编码,我找到一篇讲解比较好的文章:《详解varint编码原理》,简单来讲呢,就是用字节的最高位表示有无后续字节(1表示有,0表示无),而剩余7位用于编码数字本身。

varint编码还有个需要注意的地方就是从表示从字节的数字低位开始编码放在最前边。编码的过程我简单总结一下:

  • 把数字表示成二进制的位
  • 从右往左依次取7个位放入新的字节中
  • 如果左边还有数位,那么新字节最高位设置为1,否则为0
  • 将新字节放到编码的字节串中
  • 依次进行2、3、4步,直到左侧没有数位

之前引用的文章中,里边有一副图挺直观,贴过来:

image.png
(图源:详解varint编码原理)

代码 & 测试

知道这些,就可以进行varint编解码了,另外steem-python中帮我们实现两组代码,可以拿来略作修改后直接使用:

image.png

测试代码如下:

encode = varint(123456)
decode = varintdecode((encode))
pprint(encode)
pprint(decode)

输出结果如下:

image.png

编码结果和文中示意图的结果完全一致,可见数字123456被正确的编码/解码,有了这个基础,我就可以处理任意长度的memo了。

相关链接

Sort:  

Hi! Did you know that steemit.com is now censoring users and posts based on their opinions?
All the posts of these users are gone!
https://github.com/steemit/condenser/commit/3394af78127bdd8d037c2d49983b7b9491397296

Here's a list of some banned users:
'roelandp', 'blocktrades', 'anyx', 'ausbitbank', 'gtg', 'themarkymark', 'lukestokes.mhth', 'netuoso', 'innerhive'
See anyone you recognize? There could be more, they also have a remote IP ban list.

Will you be censored next?

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.033
BTC 63691.77
ETH 3157.03
USDT 1.00
SBD 3.84