浅析RLP-以太坊的数据编码方式

简介: ### 概述 RLP(RecursiveLength Prefix)是以太坊中序列化数据的编码方式。 既然是编码方式,下面结合代码详细看看RLP的奥秘: 官方定义: * RLP encoding is defined as follows: * For a single byte whose value is in the [0x00, 0x7f] range, th

概述

RLP(RecursiveLength Prefix)是以太坊中序列化数据的编码方式。
既然是编码方式,下面结合代码详细看看RLP的奥秘:

官方定义:

  • RLP encoding is defined as follows:

    • For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding.
    • Otherwise, if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value 0x80 plus the length of the string followed by the string. The range of the first byte is thus [0x80, 0xb7].
    • If a string is more than 55 bytes long, the RLP encoding consists of a single byte with value 0xb7 plus the length in bytes of the length of the string in binary form, followed by the length of the string, followed by the string. For example, a length-1024 string would be encoded as xb9x04x00 followed by the string. The range of the first byte is thus [0xb8, 0xbf].
    • If the total payload of a list (i.e. the combined length of all its items being RLP encoded) is 0-55 bytes long, the RLP encoding consists of a single byte with value 0xc0 plus the length of the list followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus [0xc0, 0xf7].
    • If the total payload of a list is more than 55 bytes long, the RLP encoding consists of a single byte with value 0xf7 plus the length in bytes of the length of the payload in binary form, followed by the length of the payload, followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus [0xf8, 0xff].

编码规则

[0x00, 0x7f]范围内的单字节数据

字面意思: 对于[0x00, 0x7f]范围内的单字节数据,RLP编码后的数据和编码之前是一样的。

有没有想过为什么是0x7f呢? 打开ASCII编码表会惊奇的发现ASCII编码的最大值就是0x7f, 所以RLP这个编码在[0x00, 0x7f]之内复用了ASCII编码,就是把数据当成ASCII编码使用了。

下面用以太坊的Python版本看看是不是这样:

image.png


长度在55个字节以内的字符串

字面意思: RLP编码包含一个单字节的前缀,后面跟着字符串本身,这个前缀的值是0x80加上字符串的长度。
想想为什么是0xb7的上界? 0x37的10进制数就是55, 所以单字节前缀表示的最大值就是0x80+0x37=0xb7, 事实上这个前缀表示的长度是以字节为单位的。

下面依然用Python验证一下:

image.png

上面的截图中"hello"占用5个字节,所以前缀变成了: 0x85。


长度超过55字节的字符串

字面意思: RLP编码包含一个单字节的前缀,后面跟着字符串的长度,后面再跟着字符串本身; 其中前缀的值是0xb7加上字符串长度的二进制形式的字节长度。
结构像这个样子: | 前缀 | 字符串长度 | 字符串本身 |

前缀的计算举一个例子: 如果一个字符串长度是156个字节(26个英文字母连续输入6遍), 用2进制表示十进制的156==10011100, 1个字节就可以表示156了。
所以前缀是: 0xb7+1 = 0xb8
长度是: 0x9c
则结果就是 | 0xb8 | 0x9c | 重复6遍的字母表 |

下面我们用Python验证一下:

image.png


以上是对单字节 和 字符串数据的编码说明, 接下来的两项编码规则是对list而言的。
开始之前,需要定义什么是list的总长度: 包含的各项的长度之和 + 包含的项的数量
例如: ["abc","def","ghi"] 的总长度是: 3+9=12(0xc)


list总长度为0 ~ 55字节

字面意思: RLP编码包含一个单字节的前缀,后面跟着列表中各元素项的RLP编码, 前缀的值是0xc0加上列表的总长度。
前缀取值范围是[0xc0, 0xf7], 同理 0xf7== 十进制(192+55), 其中 0xc0的十进制是 192。

以["abc","def","ghi"] 为例, 其RLP编码为: | 0xcc | 三个字符串的RLP |

Python验证:

image.png


list总长度大于55字节

字面意思: RLP编码包含: 一个单字节的前缀, 后面跟list的长度,后面再跟list中各元素项的RLP编码; 前缀的值是0xf7加上list总长度的二进制形式的字节长度(和规则3表达的计算方式相同)。
第一个前缀的取值范围是: [0xf8, 0xff], 则这个规则能表示的list最大长度是: 8字节表示的最大整数(0xff = 0xf7+0x08)。

以一个总长度超过55字节的list为例:
我们看看存储了6次a~z的list怎么表达呢? ["abc....z", "abc...z", "abc...z","abc....z", "abc...z", "abc...z"]
按照上面的规则描述, list总长度是: 0xa2(16进制), 10100010(2进制,1字节可表示), 162(10进制)

则: 前缀: 0xf7+0x01=0xf8

  总长度: 0xa2

如果是12次a~z的list呢? 总长度: 324,需要2字节表示(00000001 01000100)。
则: 前缀: 0xf7+0x02=0xf9

  总长度: 0x0144

Python验证一下:

image.png

如果细致一点, 你会发现上面的测试用0x01D代表了0x0144, 没错十六进制的0x44就是对应ASCII的D字母。


代码分析

目录
相关文章
|
7月前
|
存储 XML JSON
数据传输的艺术:深入探讨序列化与反序列化
数据传输的艺术:深入探讨序列化与反序列化
127 0
|
2月前
|
JSON 前端开发 数据格式
前端的全栈之路Meteor篇(五):自定义对象序列化的EJSON介绍 - 跨设备的对象传输
EJSON是Meteor框架中扩展了标准JSON的库,支持更多数据类型如`Date`、`Binary`等。它提供了序列化和反序列化功能,使客户端和服务器之间的复杂数据传输更加便捷高效。EJSON还支持自定义对象的定义和传输,通过`EJSON.addType`注册自定义类型,确保数据在两端无缝传递。
|
7月前
|
存储 JSON 前端开发
第四章 前后端数据交换格式详解
第四章 前后端数据交换格式详解
138 0
|
安全 算法 数据处理
Python 标准类库-因特网数据处理之Base64数据编码
Python 标准类库-因特网数据处理之Base64数据编码
154 1
|
存储 机器学习/深度学习 缓存
二十七、网络层概述和数据交换方式
二十七、网络层概述和数据交换方式
二十七、网络层概述和数据交换方式
|
自然语言处理 算法 搜索推荐
颠覆编程方式的感知编码:Stephen Wolfram雄心勃勃的全新计算模式
2002 年,出生在英国的科学家、程序员及创业家 Stephen Wolfram 的《一种新科学》刚刚发布,其颠覆传统的追求知识方式引发的惊愕、争议与指责就已经铺天盖地。上个月初,他在博客中披露了自己的一个即将完成的新项目,称该项目将会对技术世界乃至于技术以外的世界产生深远影响。
178 0
颠覆编程方式的感知编码:Stephen Wolfram雄心勃勃的全新计算模式
|
区块链 C++
BC之SC:区块链之智能合约——与传统合约的比较以及智能合约模型部署原理、运行原理相关配图(一)
BC之SC:区块链之智能合约——与传统合约的比较以及智能合约模型部署原理、运行原理相关配图
BC之SC:区块链之智能合约——与传统合约的比较以及智能合约模型部署原理、运行原理相关配图(一)
BC之SC:区块链之智能合约——与传统合约的比较以及智能合约模型部署原理、运行原理相关配图(二)
BC之SC:区块链之智能合约——与传统合约的比较以及智能合约模型部署原理、运行原理相关配图
BC之SC:区块链之智能合约——与传统合约的比较以及智能合约模型部署原理、运行原理相关配图(二)
|
Rust JavaScript 前端开发
区块链开发(八)以太坊不同语言客户端地址
区块链开发(八)以太坊不同语言客户端地址
140 0
|
区块链 算法 开发者
带你读《深入理解以太坊》之一:以太坊概述
这是一本从原理和实践两个层面系统、深入讲解以太坊技术的专著,从设计理念、技术架构、共识算法、智能合约、以太坊虚拟机、开发工具、DApp开发、企业以太坊解决方案、跨链技术等近10个方面进行了详细讲解,既适合初学者系统学习以太坊的原理和应用开发,又适合有一定基础的开发者深入掌握以太坊的底层运行机制。

热门文章

最新文章