** 原创勿转 **

这是在看devp2p时看到的,英文原文地址:https://github.com/ethereum/wiki/wiki/RLP

RLP:  Recursive Length Prefix,中文直译“递归长度前缀”(很别扭有没有,不管叫什么,它就在那里)。 实际上就是一种数据编码方式,类似Base64之类的。

一.    推荐的两种编码形式
   . 使用[[k1,vv1],[k2,v2]...],  其中k1,k2,... 是字典顺序
   . 使用Patricia Tree, 以太坊中使用这种方式

二. 编码函数需要一个数据项(item)

     对于item的定义:
     . 串(比如字节数组,  golang: []byte{}, java: byte[])是一个item
     . item列表也是一个item

     例:空string, 空列表[], "cat",  列表["cat", ["puppy", "cow"], "horse", [[]], "pig", [""], "sheep"]
    
     在原文中, string并不是一个字符串,是"a certain number of bytes of binary data"的同义词, 即某个特定长度的二进制数据, 对于具体的数据,长度是固定的。

可以理解为字节数组, 而不仅仅是字符串。

三. 具体的编码过程

其中第一个字节是特殊的,以byte0表示, byte0 按其值将[0x00,0xff]划分为5个部分:   [0x00,0x7f],   [0x80,0xb7],   [0xb8, 0xbf],   [0xc0, 0xf7],   [0xf8, 0xff]
 
  *** 这里的方括号表示区间, 同时编码结果也用方括号表示,比如[0x83, 'c','a','t'], 注意区分。
 
  1.  单字节
       单字节值的取值范围在[0x00, 0x7f]之间的数据,编码等于这个字节
       生成数据的格式:[byte0], 所以 byte0的取值范围是[0x00, 0x7f]
       比如: "A", 0x41, 编码就是[0x41]
       
       对于[0x80, 0xff]的单字节,适用下一条规则
      
  2.  0-55个字节的数据

这包括1里排除的[0x80, 0xff]单字节, 它的编码数据是这样产生的:
       编码格式:[byte0, 原始数据]
       byte 0 = 0x80 + 原始数据的长度, 所以byte0的取值范围就是0x80 + (0-55) = [0x80, 0x80+55] = [0x80, 0xb7]   (0x80= 128,0xb7=183)

比如:
          0x95,  长度为1, 那么byte0 = 0x80 + 1 = 0x81,  编码为[0x81, 0x95], 这个是1里排除的数据
          "cat",  长度为3,    那么byte0 = 0x80 + 3 = 0x83,  编码为[0x83, 'c', 'a', 't']
          string('null')  = 0x00 = [0x80 + 0(长度为0, 空格按1规则编码)] = [0x80]         
       
  3.  对于长度大于55的数据
       编码格式: [byte0, 长度(不一定几个字节), 原始数据]
       byte0 = 0xb7 + 长度占用的字节。 长度是整数, 比如15,那么它占用1个字节,说得绕一点,就是长度的长度
       长度:就是其二进制表示
       
       比如:长度为1024的数据, byte0 = 0xb7 + 2 (1024的十六进制表示为0x0400, 所以占用两个字节)  = 0xb9
       整个数据的编码就是[0xb9, 0x04, 0x00, 原始数据]
       
       长度既然是整数, 其在内存里最多占用8个字节, 所以byte0的取值范围:[0xb7 + (1-8)] = [0xb8, 0xbf]
       
 4.  对于列表来说

(对于列表,我的理解应该算是串的数组吧。)

如果它的每个数据都被编码过了,而整个列表的数据长度是0-55, 那么
      编码格式:[byte0,列表各项编码后的数据]
      byte0 = 0xc0 + 列表所有数据的长度,  那么byte0 = 0xc0 + (0-55) = [0xc0, 0xc0 + 55] = [0xc0, 0xf7]   (0xc0=192, 0xf7=247)
      
      比如:"cat" = [0x83,'c','a','t'],  "dog" = [0x83, 'd','o','g'],  这两个适用规则2
                byte0 = 0xc0 + 8("cat"和"dog"编码后的总长度)  = 0xc8
                ["cat", "dog"] = [0xc8,  0x83, 'c','a','t',  0x83, 'd','o','g']
                
5.  相对于规则4, 如果列表编码后数据总长度大于55
     编码格式: [byte0, 长度,列表各项编码后数据]
     byte0 = 0xf7 + 长度的长度, 所以byte0的取值范围:[0xf7 + (1-8)] = [0xf8, 0xff], 长度的长度取值是1个字节到8个字节

总的来说,对于超过55的长度, 要使用长度的长度。

解码是相反的过程,有时间再写吧。

RLP的更多相关文章

  1. RLP编码

    RLP(Recursive Length Prefix, 递归长度前缀编码),是Ethereum中对象序列化的一个主要的编码方式,其目的是对任意嵌套的二进制数据的序列进行编码. RLP的目的仅仅是编码 ...

  2. 以太坊RLP用法-go-ethereum学习

    RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式.RLP的唯一目标就是解决结构体的编码问题:对原子数据类型(比如,字符串,整数型, ...

  3. RLP(转发注明出处)

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

  4. 以太坊系列之一: 以太坊RLP用法-以太坊源码学习

    RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式.RLP的唯一目标就是解决结构体的编码问题:对原子数据类型(比如,字符串,整数型, ...

  5. RLP序列化算法

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

  6. centos6.3与jexus5.4.4配置支持php(wordpress)

    centos6.3与jexus5.4.4配置支持php,并搭建自己的wordpress博客,供那些在Linux平台下想让 php和asp.net一起跑的初学者参考. 1.搭建webserver 首先准 ...

  7. Xamarin.iOS开发初体验

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0

  8. linux查看端口及端口详解

    今天现场查看了TCP端口的占用情况,如下图   红色部分是IP,现场那边问我是不是我的程序占用了tcp的链接,,我远程登陆现场查看了一下,这种类型的tcp链接占用了400多个,,后边查了一下资料,说E ...

  9. js下载项目中的文件

    项目中有一个连接是下载视频插件,放到服务器上,不能io输出,所以指定地址直接下载 <div id="objInfo"> <jsp:include page=&qu ...

随机推荐

  1. 》》mui--图片轮播

    mui框架内置了图片轮播插件,通过该插件封装的JS API,用户可以设定是否自动轮播及轮播周期,如下为代码示例: //获得slider插件对象 var gallery = mui('.mui-slid ...

  2. OpenCV探索之路(二十八):Bag of Features(BoF)图像分类实践

    在深度学习在图像识别任务上大放异彩之前,词袋模型Bag of Features一直是各类比赛的首选方法.首先我们先来回顾一下PASCAL VOC竞赛历年来的最好成绩来介绍物体分类算法的发展. 从上表我 ...

  3. hdu1570(排列和组合公式的应用)

    题意: 给出字符A.则求全排列 A(n,m)=n!/(n-m)! 给出字符C.则求全组合 C(n,m)=n!/(m!*(n-m)!) http://acm.hdu.edu.cn/showproblem ...

  4. Sqoop2安装记录

    我是採用的源代码编译的包安装的, 主要是考虑到会对部分功能做裁剪或增强, 详细源代码编译方式能够參考另外一篇博文<编译Sqoop2错误解决>.然后从dist/target文件夹下拷贝sqo ...

  5. .NET Core 已经实现了PHP JIT,现在PHP是.NET上的一门开发语言

    12月23日,由开源中国联合中国电子技术标准化研究院主办的2017源创会年终盛典在北京万豪酒店顺利举行.在本次大会上,链家集团技术副总裁.PHP 开发组核心成员鸟哥发表了以 " PHP Ne ...

  6. 几条jQuery代码片段助力Web开发效率提升

    平滑滚动至页面顶部 以下是jQuery最为常见的一种实现效果:点击一条链接以平滑滚动至页面顶部.虽然没什么新鲜感可言,但每位开发者几乎都用得上. $("a[href='#top']" ...

  7. REST设计规则

    1.简介 REST(Representational State Transfer), 表述性状态转移是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格. REST只是一 ...

  8. MongoDB的CURD命令

    1.启动客户端 在MongDB服务成功启动的情况下,打开cmd,在MongDB的bin文件目录下执行MongDB命令 可以看到MongDB版本号3.0.7与默认连接的数据库test.test数据库是系 ...

  9. 挂载mount、卸载umount、挂载光盘U盘

    mount [root@localhost ~]# mount sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel) ...

  10. JavaWeb框架_Struts2_(五)----->Struts2的标签库

    1.  Struts2的标签库 1.1 Struts2标签库概述 Struts2的标签库可以分为以下3类:用户界面标签.非用户界面标签.AJAX标签; 2.1.1 Struts2标签库的分类和使用 1 ...