以太坊源码解析 - RLP(理论)

RLP(Recursive Length Prefix),叫递归长度前缀编码,它是以太坊序列化所采用的编码方式。RLP主要用于以太坊中数据的网络传输和持久化存储。

定义

RLP实际只给以下两种类型数据编码:

  • byte数组
  • byte数组的数组,称之为列表

byte数组

规则1:对于值在[0, 127]之间的单个字节,其编码是其本身。

例:a 的编码是 97

规则2: 如果byte数组长度l <= 55,编码的结果是数组本身,再加上128+l作为前缀。

例:abc 编码结果是131 97 98 99,其中131=128+len(“abc”),97 98 99依次是a b c

规则3: 如果数组长度大于55, 编码结果第一个是183加上字符串长度所占用的字节数,然后是数组长度的本身的编码,最后是byte数组的编码。

编码下面这段字符串:

The length of this sentence is more than 55 bytes, I know it because I pre-designed it

这段字符串共86个字节,而86的编码只需要一个字节,那就是它自己,因此,编码的结果如下:

184 86 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前三个字节的计算方式如下:

184 = 183 + 1,因为数组长度86编码后仅占用一个字节。
86即数组长度86
84是T的编码

编码一个重复1024次”a”的字符串,其结果为:185 4 0 97 97 97 97 97 97 ...

1024 二进制 00000100 00000000 ,一个字节为8位,所以 1024 的字节数为 2
4 0 是数组长度的编码

185=183+2 ,数组长度1024占用2个字节

1024占用了2个字节,根据规则1将1024分成两个字节即0000010000000000,换算成十进制就是40

列表

规则4:如果列表长度小于55,编码结果第一位是192加列表长度的编码的长度,然后依次连接各子列表的编码。

例6:[“abc”, “def”]的编码结果是 200 131 97 98 99 131 100 101 102

其中 abc 的编码为 131 97 98 99 , def 的编码为131 100 101 102。两个子字符串的编码后总长度是8,因此编码结果第一位计算得出:192 + 8 = 200

规则5:如果列表长度超过55,编码结果第一位是247加列表长度的编码长度所占用的字节数,然后是列表长度本身的编码,最后依次连接各子列表的编码。

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

的编码结果是:

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前两个字节的计算方式如下:

列表长度 88 = 86 + 2,在规则3的示例中,长度为86,而在此例中,由于有两个子字符串,每个子字符串本身的长度的编码各占1字节,因此总共占2字节。

列表长度的编码长度为 1
第1个字节为248 = 247 +1
第2个字节为 88

第3个字节179依据规则2得出179 = 128 + 51
第55个字节163同样依据规则2得出163 = 128 + 35

RLP解码

解码时,首先根据编码结果第一个字节f的大小,执行以下的规则判断:

  • 如果f∈ [0,128), 那么它是一个字节本身。

  • 如果f∈[128,184),那么它是一个长度不超过55的byte数组,数组的长度为 l=f-128

  • 如果f∈[184,192),那么它是一个长度超过55的数组,长度本身的编码长度ll=f-183,然后从第二个字节开始读取长度为ll的bytes,按照BigEndian编码成整数l,l即为数组的长度。

  • 如果f∈(192,247],那么它是一个编码后总长度不超过55的列表,列表长度为l=f-192。递归使用规则1~4进行解码。

  • 如果f∈(247,256],那么它是编码后长度大于55的列表,其长度本身的编码长度ll=f-247,然后从第二个字节读取长度为ll的bytes,按BigEndian编码成整数l,l即为子列表长度。然后递归根据解码规则进行解码。

ASCII

ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUT32(space)64@96
1SOH33!65A97a
2STX3466B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李柏林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值