RLP序列化
RLP:这是一种对任意结构的二进制数据(字节数组)进行编码的序列化方法
什么是序列化?
为什么要序列化?
序列化的方法:Json序列化、FastJson序列化、xml序列化…等等,RLP正是序列化方法的一种,以太坊中使用了大量的RLP序列化
RLP序列化处理的两项数据
区块、交易等数据结构在持久化时会先经过RLP编码后再存储到数据库中,RLP编码的定义只处理两类数据:
RLP序列化采取的5项规则:
对于值在[0, 127]之间的单个字节,其编码是其本身。
- 例1:a的编码是97。 如果byte数组长度l <= 55,编码的结果是数组本身,再加上128+l作为前缀。
- 例2:abc编码结果是131 97 98 99.其中131=128+len(“abc”),97 98 99依次是a b c。
如果数组长度大于55,编码结果第一个是183加数组长度的编码的长度,然后是数组长度的本身的编码,最后是byte数组的编码。
- 例3:“The length of this sentence is more than 55 bytes, I know it because I pre-designed it” = [183 + 1,86, ‘T’, ‘h’, ‘e’, ‘ ’, ’l’, ‘e’, … , ‘d’, ‘ ’, ‘i’, ’t’]
这里一定要注意的是:加上的数组长度的编码,86是数组的长度,86编码之后占用1个字节(在1到128之间),所以才加上1
如果列表长度小于55,编码结果第一位是192加列表长度的编码的长度,然后依次连接各子列表的编码。 - 例4: [“abc”, “def”]的编码结果是200 131 97 98 99 131 100 101 102。其中abc的编码为131 97 98 99, def的编码为131 100 101 102。两个子字符串的编码后总长度是8,因此编码结果第一位计算得出:192 + 8 = 200。 如果列表长度超过55,编码结果第一位是247加列表长度的编码长度,然后是列表长度本身的编码,最后依次连接各子列表的编码。 这里一定要注意的是:加上的是列表长度的编码长度!类似于规则3
ps:
列表长度是指子列表编码后的长度之和。 规则1~3定义了byte数组的编码方案(也就是第一种数据结构)下面介绍列表(第二种数据结构)的编码规则
现在我们看一个较复杂的例子:
列表第一项字符串abc根据规则2,编码结果为131 97 98 99,长度为4。
利用python写的RLP
def rlp_encode(input): if isinstance(input,str): if len(input) == 1 and chr(input) < 128: return input #规则一 else: return encode_length(len(input),128) + input #规则二和规则三 elif isinstance(input,list): output = '' for item in input: output += rlp_encode(item) #递归的去遍历 return encode_length(len(output),192) + output #规则四和规则五 def encode_length(L,offset): if L < 56: return chr(L + offset) elif L < 2568: BL = to_binary(L) return chr(len(BL) + offset + 55) + BL else: raise Exception("input too long") def to_binary(x): return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256)
实际中的使用是个怎么样子?
RLP分析
- RLP最大的优点是在充分利用字节的情况下,同时支持列表结构,也就是说可以很轻易的利用RLP存储一个树状结构。
以上我们可以看出RLP编码的设计思想,就是通过首字节快速判断一串编码的类型,充分利用了一个字节,两个字节的存储空间,将0x7f以后的值赋予了新的含义。
- 程序处理RLP编码时也非常容易。
根据首字节就可以判断出这段编码的类型,同时调用不同的方法进行解码,和JSON编码类似,支持嵌套的结构,通过递归调用可以将整个RLP快速还原成一颗树,或者转译成一个JSON结构,便于其他程序使用
- 所以理论上RLP可以编码任何数据。
RLP使用首字节存储长度的位数,再用后续的字节表明整体字符串的长度,根据规则二计算,RLP可以支持的单个最大字符串长度为2的64次方,这无疑是个天文数字
参考目录
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/208910.html原文链接:https://javaforall.net
