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. AjaxFileUpload 方法与原理分析

    AjaxFileUpload需求 传统的form表单方式上传文件,  必然会刷新整个页面. 那么在不刷新界面的情况下实现文件的上传呢? 在 HTML4下, 聪明的程序员们发明了 ajax file u ...

  2. .net下的跨域问题

    环境: IIS7.0 MVC 4.0     公司官网 asp.net      需要的报名系统,需要有后台管理 由于是配合传统产业,所以MVC系统的数据,是由AIPS系统提供. (制作前是考虑去年用 ...

  3. 【转】赞一下huicpc035

    以下转自:http://hi.baidu.com/fpkelejggfbfimd/item/99421eaefa93a814a9cfb722 本来以为HNU的huicpc035和我一样退役了,后来听说 ...

  4. JAVA基础语法。

    1.java数据类型和变量布尔型.短整型.整型.长整型.浮点型.双精度型.字符型.字节型.8中数据类型结构.2. 变量的作用域3.常量.关键字.标识符4.运算符和表达式 4.1算术运算符 4.2位运算 ...

  5. ReferenceEquals和 == 和equals()的比较

    对于这几点的区别网上经常有各种答案,而且常常会出现答案之间是互相矛盾的.要嘛就是根本含糊的解释不清楚,只是把测试结果扔上来并没有言简意赅的写出他们之间的比较.难道面试的时候考官问你,你也要在纸上写一大 ...

  6. android 多点

    引用:http://blog.163.com/fenglang_2006/blog/static/13366231820108205274325/ 第一章摘要 在Linux内核支持的基础上,Andro ...

  7. servlet1

    1.jsp其实就是servlet 2.一个java类实现servlet接口,然后在浏览器端访问即可

  8. SnowNLP:一个处理中文文本的 Python 类库

    https://segmentfault.com/a/1190000000362372

  9. Tsung安装与使用

    Tsung安装与使用 Tsung安装与使用的详细说明,包括测试场景的脚本配置说明 Ray 2013/11/11   目录 安装tsung Tsung运行环境安装... Tsung安装... 使用Tsu ...

  10. hadoop2.0初识1.3

    1.配置分布式hadoop 1.1 准备三台测试机(虚拟机就可以) 1.1.1 将life-hadoop虚拟机克隆2个分别为life-hadoop02和life-hadoop03 1.1.2 查看ip ...