RLP编码
RLP(Recursive Length Prefix, 递归长度前缀编码),是Ethereum中对象序列化的一个主要的编码方式,其目的是对任意嵌套的二进制数据的序列进行编码。
RLP的目的仅仅是编码一些数据结构,而像string,int,float这些特定的原子数据类型就留给了更高阶的编码协议。在以太坊中,整形必须用没有前导0的大端格式编码(因此整数0则是一个空的数组)。
如果要编码一个字典,推荐使用两种规范的编码格式——一是通过key的字典序来组织字典[[k1,v1],[k2,v2]……],另一种是以太坊中使用的高层的Patricia Tree。
定义:
RLP编码接受一个item。Item的定义如下:
- 一个string(例如,byte array)是一个item
- Item的列表是一个item
例如一个空的string是一个item,同样一个单词“cat”也是一个item。包含任意个string的列表(例如,["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"])也是一个item。
RLP编码按一下定义:
- 对于值在[0x00,0x7f]范围内的单字节(ascii表定义的字符),其RLP编码就是其自身
- 否则,如果一个string的长度是0-55字节,那么他的RLP编码是在string开头加一个字节,这个字节的值是\x80加上string的长度,即[\x80, \xb7]。
- 如果一个string的长度大于55,那么RLP编码是在string开头加一个字节,这个字节的值等于\xb7加上string长度的二进制编码的字节长度,然后后面跟着string的长度。比如一个长度为1024字节的string,其长度位1024=\x04\x00,长度为2个字节,因此RLP编码头字节的值为\xb7+\x02=\xb9,跟着\x04\x00。String的RLP编码即\xb9\x04\x00(string)。第一个字节的范围为[0xb8,0xbf]
- 如果一个列表的总的payload(应该是它包含的所有item的编码后长度的和)的长度为0-55,那么list的RLP编码在其item的RLP编码的串联前加上一个字节,这个字节的值是0xc0加上列表的长度(item经过RLP编码后串联记起来的长度)。比如RLP([“cat”,“dog”])= [ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]。所以头字节的范围为[0xc0,0xf7]
- 如果一个list的payload的长度大于55,其RLP编码是list的item的RLP编码的串联,前面加上一个表示payload长度的字节,前面再加上一个payload长度的二进制表示的字节长度。
python代码如下:
#!/usr/bin/env python
#encoding=utf-8
# Author: xuyuzhuang - xuyuzhuang@buaa.edu.cn
# Last modified: 2016-06-06 22:16
# Filename: rlp_encoding.py
# Description: Recursive Length Prefix
def rlp_encode(input_):
if isinstance(input_, str):
if len(input_) == 1 and ord(input_) < 0x80: return input_
else : return encode_length(len(input_),0x80) + input_
elif isinstance(input_, list):
output = ''
for item in input_: output += rlp_encode(item)
return encode_length(len(output),0xc0) + output
def encode_length(L,offset):
if L < 56:
return chr(L + offset)
elif L < 256**8: #(2**8)**8
BL = to_binary(L)
return chr(len(BL) + offset + 55) + BL
else:
raise Exception("input to long!")
def to_binary(x):
if x == 0:
return ''
else:
return to_binary(int(x/256))+chr(x%256)
def my_print(string):
for i in string:
if ord(i) > 32 and ord(i) < 127:
print i,
else:
print hex(ord(i)),
if __name__ == "__main__":
#string = "dog"
string = ["cat", "dog"]
#string = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
my_print(rlp_encode(string))
对于“dog”,输出为

对于["cat", "dog"],输出为

对于"Lorem ipsum dolor sit amet, consectetur adipisicing elit",输出为

参考:https://github.com/ethereum/wiki/wiki/RLP
RLP编码的更多相关文章
- RLP(转发注明出处)
目录 RLP序列化 什么是序列化? 为什么要序列化? RLP序列化处理的两项数据 RLP序列化采取的5项规则: 利用python写的RLP 实际中的使用是个怎么样子? RLP分析 参考目录 @ RLP ...
- RLP序列化算法
RLP RLP(Recursive Length Prefix)递归长度前缀编码,是由以太坊提出的序列化/反序列化标准,相比json格式体积更小,相比protobuf对多语言的支持更强. RLP将数据 ...
- 源码阅读 etherum-block.py
def calc_difficulty(parent, timestamp): config = parent.config offset = parent.difficulty // config[ ...
- Merkle Patricia Tree (MPT) 树详解
1. 介绍 Merkle Patricia Tree(简称MPT树,实际上是一种trie前缀树)是以太坊中的一种加密认证的数据结构,可以用来存储所有的(key,value)对.以太坊区块的头部包 ...
- RChain节点通信机制(上)
在介绍RChain的通信机制之前,先简单介绍一些以太坊的通信机制,它包括以下几个方面,如下详细了解以太坊的通信机制,可以查看https://github.com/ethereum/devp2p/blo ...
- 从头到尾使用Geth的说明-2-cli可用命令-有2个地方标红,之后查查源码后看看能不能解决
geth - the go-ethereum command line interface 以太坊命令行接口 格式: geth [options] command [command options] ...
- ethereum/EIPs-191 Signed Data Standard
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-191.md eip title author status type category c ...
- ethereumjs/ethereumjs-util
ethereumjs/ethereumjs-util Most of the string manipulation methods are provided by ethjs-util 更多的字符串 ...
- ConsenSys/eth-lightwallet(browserless)
https://github.com/ConsenSys/eth-lightwallet LightWallet A minimal ethereum javascript wallet.一个小型的钱 ...
随机推荐
- CentOS6修改主机名(hostname)及 修改/etc/hosts 文件,增加ip和hostname的映射关系(转)
CentOS修改主机名(hostname) 需要修改两处:一处是/etc/sysconfig/network,另一处是/etc/hosts,只修改任一处会导致系统启动异常.首先切换到root用户. ...
- vim - Highlight unwanted spaces
http://vim.wikia.com/wiki/VimTip396 precondition: set hlsearch" Show all tabs:/\t" Show tr ...
- nginx优化 突破十万并发
一.一般来说nginx 配置文件中对优化比较有作用的为以下几项: 1. worker_processes 8; nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu ...
- UE4 自定义物理表面类型(Surface Type)
如果想在UE4中实现在接触到不同物体表面时发出不同的声音或者效果时,比如人在不同的表面上速度会不同,子弹打到不同的表面时会出现不同的特效等,我们可以使用UE4中的表面类型来实现(Surface Typ ...
- C# 遍历类的属性并取出值
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 今天有点胡思乱想,想遍历MVC Model的属性并 ...
- APP定制开发:APP软件开发的语言和开发环境
APP软件开发是移动互联网开发公司常开发的一种手机应用系统,对于刚刚进入APP软件开发领域的新手来说,选择什么编程语言和需要什么开发环境来开发APP软件是常遇到的问题.下面亿合科技小编来为大家分享下: ...
- 20145320《Java程序设计》第9周学习总结
20145320<Java程序设计>第9周学习总结 教材学习内容总结 16.整合数据库 JDBC(java DateBase Connectivity)是用于执行SQL的解决方案,开发人员 ...
- angularJS ng-grid 配置
以下是按我的需求修改的 简单的demo 可以自己扩展 HTML: <!DOCTYPE html> <html class="no-js" ng-app=&quo ...
- python 学习笔记九 队列,异步IO
queue (队列) 队列是为线程安全使用的. 1.先入先出 import queue #测试定义类传入队列 class Foo(object): def __init__(self,n): self ...
- CentOS 7下关于systemd的一些唠叨话二:systemd服务脚本的编写
CentOS 7继承了RHEL 7的新的特性,例如强大的systemd,而systemd的使用也使得以往系统服务的/etc/init.d的启动脚本的方式就此改变,也大幅提高了系统服务的运行效率.但服务 ...