RLP 编码

RLP 编码

RLP(Recursive Length Prefix,递归长度前缀),关于介绍RLP的文章也挺多的,这里说说我对它的理解。RLP 编解码的精髓就在它的名字里,第一是R,对象可以是递归的,本质上是支持list的编码。第二是LP,长度前缀,第一个字节暗藏了很多信息呀,有关于接下来这个对象的长度,从长度可以推断出这个对象的类型。

支持哪些类型嘞:

  1. byte. 单字节,并且这个字节的value得小于0x80。这个时候,它的前缀就是这个byte的值,紧凑。
  2. string. string分为两种,长度小于56的和长度不小于56的。小于56的,它的前缀就是 0x80+string长度,否则就是 0xB8+string长度这个数字大端表示的长度。
  3. list. list也是分两种,长度小于56和长度不小于56的。小于56的,前缀就是0xC0+整个list表示的长度,否则前缀就是 F8+ 整个list表示的长度这个数字大端表示的长度。

从上面的类型表示可以推断出,空string和空list的表示分别为0x80和0xC0.

注意:map类型是不能直接被序列化(一般先转为二纬数组),负数类型不能被序列化。

例子:

    type A struct {
        X uint
        Y uint
    }

{X:1,Y:1} ==> 194 1 1 , 194表示长度为2的list,第一个属性是单byte,值为1。第二个属性为单byte,值为1.

{X:0,Y:0} ==> 194 128 128, 194表示长度为2的list,128表示值为0的string。

{X:233,Y:233} ==> [196 129 233 129 233], 196表示长度为4的list,129表示这个长度为1的string,string的值是233。

    type A struct {
        X uint
        Z string
        //Y []uint `rlp:"tail"`
        Y []uint
    }

{X:1,Z:"aaa",Y:[]uint{1,2,3}} ==> [201 1 131 97 97 97 195 1 2 3]

201 表示这个是长度为9的list,1表示属性值是1,131表示长度为3的string, 195表示长度为3的list,list每个元素值是1,2,3/

有几个tag:

  1. nil,nilString,nilList, 表示值是nil的时候,应该被encode成空string还是空list,默认情况下string,uint,bool和byteArray会是空string,其他的是空list。
  2. tail,要求是最后一个field,并且是slice类型,可以省略一个前缀。

你可能感兴趣的:(RLP 编码)