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. java math library

    https://github.com/jroyalty/jglm https://github.com/JOML-CI/JOML

  2. JVM常见配置汇总

    堆设置 -Xms:初始堆大小 -Xmx:最大堆大小 -XX:NewSize=n:设置年轻代大小 -XX:NewRatio=n:设置年轻代和年老代的比值.如:为3,表示年轻代与年老代比值为1:3,年轻代 ...

  3. window.event对象详尽解析

    event代表事件的状态,例如触发event对象的元素.鼠标的位置及状态.按下的键等等. event对象只在事件发生的过程中才有效. event的某些属性只对特定的事件有意义.比如,fromEleme ...

  4. Eclipse下编写的web项目部署到tomcat下

    之前都是用myeclipse编写web项目,编写好然后在myclipse上配置的tomcat下的webapps文件想项目复制到其他tomcat下就能运行了. 最近学习jquery,将eclipse编写 ...

  5. 阿里云OneinStack,Linux下tomcat命令

    阿里云OneinStack,Linux下tomcat命令 Linux下如何查看tomcat是否启动在Linux系统下,重启Tomcat使用命令操作的首先,进入Tomcat下的bin目录cd /usr/ ...

  6. javascript,jQuery,trim()

    JavaScript trim() Syntax string.trim() The trim() method removes whitespace from both sides of a str ...

  7. php连接Access数据库错误及解决方法

    <?php $connstr="DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("data.m ...

  8. JAVA基础知识之JDBC——RowSet

    RowSet概念 在C#中,提供了一个DataSet,可以把数据库的数据放在内存中进行离线操作(读写),操作完成之后再同步到数据库中去,Java中则提供了类似的功能RowSet. RowSet接口继承 ...

  9. 【Tarjan】+【SPFA】APIO2009 Atm

    一.算法介绍 tarjan——求解有向图强连通分量.这个算法在本人的一篇blog中有介绍,这里就不赘述了.贴上介绍tarjan的的blog链接:http://www.cnblogs.com/Maki- ...

  10. 【Spring】Spring的定时任务

    > 参考的优秀文章 Task Execution and Scheduling > 版本说明 <dependencies> <dependency> <gro ...