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编码的更多相关文章

  1. RLP(转发注明出处)

    目录 RLP序列化 什么是序列化? 为什么要序列化? RLP序列化处理的两项数据 RLP序列化采取的5项规则: 利用python写的RLP 实际中的使用是个怎么样子? RLP分析 参考目录 @ RLP ...

  2. RLP序列化算法

    RLP RLP(Recursive Length Prefix)递归长度前缀编码,是由以太坊提出的序列化/反序列化标准,相比json格式体积更小,相比protobuf对多语言的支持更强. RLP将数据 ...

  3. 源码阅读 etherum-block.py

    def calc_difficulty(parent, timestamp): config = parent.config offset = parent.difficulty // config[ ...

  4. Merkle Patricia Tree (MPT) 树详解

    1.    介绍 Merkle Patricia Tree(简称MPT树,实际上是一种trie前缀树)是以太坊中的一种加密认证的数据结构,可以用来存储所有的(key,value)对.以太坊区块的头部包 ...

  5. RChain节点通信机制(上)

    在介绍RChain的通信机制之前,先简单介绍一些以太坊的通信机制,它包括以下几个方面,如下详细了解以太坊的通信机制,可以查看https://github.com/ethereum/devp2p/blo ...

  6. 从头到尾使用Geth的说明-2-cli可用命令-有2个地方标红,之后查查源码后看看能不能解决

    geth - the go-ethereum command line interface 以太坊命令行接口 格式: geth [options] command [command options] ...

  7. ethereum/EIPs-191 Signed Data Standard

    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-191.md eip title author status type category c ...

  8. ethereumjs/ethereumjs-util

    ethereumjs/ethereumjs-util Most of the string manipulation methods are provided by ethjs-util 更多的字符串 ...

  9. ConsenSys/eth-lightwallet(browserless)

    https://github.com/ConsenSys/eth-lightwallet LightWallet A minimal ethereum javascript wallet.一个小型的钱 ...

随机推荐

  1. jQuery源代码阅读之二——jQuery静态属性和方法

    一.jQuery.extend/jQuery.fn.extend //可接受的参数类型如下:jQuery.extend([deep],target,object1,[objectN]) jQuery. ...

  2. Java 使用jaxp修改节点

    <?xml version="1.0" encoding="UTF-8" standalone="no"?> <perso ...

  3. RDIFramework.NET ━ 9.4 角色管理 ━ Web部分

    RDIFramework.NET ━ .NET快速信息化系统开发框架 9.4 角色管理 -Web部分 角色管理模块主要为了方便框架权限的分配,提高权限分配的效率,减少重复设置权限的工作量.角色(用户组 ...

  4. 一个安邦逻辑漏洞爆破密码的py脚本

    漏洞地址: 安邦保险集团存在逻辑漏洞可遍历用户ID暴力破解用户原始密码进而重置用户密码(附脚本) http://www.wooyun.org/bugs/wooyun-2010-0119851 脚本PO ...

  5. C++之路进阶——codevs1281(Xn数列)

    1281 Xn数列  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master       题目描述 Description 给你6个数,m, a, c, x0, n, ...

  6. ajax异步处理时,如何在JS中获取从Servlet或者Action中session,request

    ssh项目中,我需要登陆某个页面(如a.jsp),通过onblur()鼠标失去焦点后来触发js函数(函数是ajax请求)请求到相应的action,处理完成后将数据存放到session对象里面,然后在a ...

  7. 如何知道btree树的高度

    来自网络,总结到这里: 当我想看btree树高度的时候,筛选出来这篇文章"为什么 B-tree 在不同著作中度的定义有一定差别?",知道了高度的算法是这个公式:但是里面又提高t和出 ...

  8. asp批量查询

    在做asp查询时候 借鉴的一些代码 留个纪念....... <!-- #include file="conn.asp"--> <html> <head ...

  9. Linux之 sort,uniq,cut,wc命令详解

    sort sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序. sort语法 ...

  10. atomic vs. nonatomic

    Declaring a property atomic makes compiler generate additional code that prevents concurrent access ...