欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

RLP編碼介紹-創(chuàng)新互聯(lián)

定義

RLP(Recursive Length Prefix,遞歸長度前綴)是一種編碼算法,用于編碼任意的嵌套結構的二進制數(shù)據(jù),它是以太坊中數(shù)據(jù)序列化/反序列化的主要方法,區(qū)塊、交易等數(shù)據(jù)結構在持久化時會先經(jīng)過RLP編碼后再存儲到數(shù)據(jù)庫中。

在鷹潭等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設 網(wǎng)站設計制作按需策劃設計,公司網(wǎng)站建設,企業(yè)網(wǎng)站建設,成都品牌網(wǎng)站建設,成都全網(wǎng)營銷推廣,外貿(mào)網(wǎng)站制作,鷹潭網(wǎng)站建設費用合理。

RLP編碼的定義只處理兩類數(shù)據(jù):一類是字符串(例如字節(jié)數(shù)組),一類是列表。字符串指的是一串二進制數(shù)據(jù),列表是一個嵌套遞歸的結構,里面可以包含字符串和列表,例如["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]就是一個復雜的列表。其他類型的數(shù)據(jù)需要轉(zhuǎn)成以上的兩類,轉(zhuǎn)換的規(guī)則不是RLP編碼定義的,可以根據(jù)自己的規(guī)則轉(zhuǎn)換,例如struct可以轉(zhuǎn)成列表,int可以轉(zhuǎn)成二進制(屬于字符串一類),以太坊中整數(shù)都以大端形式存儲。

RLP編碼規(guī)則

  1. 對于單個字節(jié),如果它的值范圍是[0x00, 0x7f],它的RLP編碼就是它本身。
  2. 否則,如果一個字符串的長度是0-55字節(jié),它的RLP編碼包含一個單字節(jié)的前綴,后面跟著字符串本身,這個前綴的值是0x80加上字符串的長度。由于被編碼的字符串大長度是55=0x37,因此單字節(jié)前綴的大值是0x80+0x37=0xb7,即編碼的第一個字節(jié)的取值范圍是[0x80, 0xb7]。
  3. 如果字符串的長度大于55個字節(jié),它的RLP編碼包含一個單字節(jié)的前綴,后面跟著字符串的長度,后面再跟著字符串本身。這個前綴的值是0xb7加上字符串長度的二進制形式的字節(jié)長度,說的有點繞,舉個例子就明白了,例如一個字符串的長度是1024,它的二進制形式是10000000000,這個二進制形式的長度是2個字節(jié),所以前綴應該是0xb7+2=0xb9,字符串長度1024=0x400,因此整個RLP編碼應該是\xb9\x04\x00再跟上字符串本身。編碼的第一個字節(jié)即前綴的取值范圍是[0xb8, 0xbf],因為字符串長度二進制形式最少是1個字節(jié),因此最小值是0xb7+1=0xb8,字符串長度二進制大是8個字節(jié),因此大值是0xb7+8=0xbf。
  4. 如果一個列表的總長度(列表的總長度指的是它包含的項的數(shù)量加它包含的各項的長度之和)是0-55字節(jié),它的RLP編碼包含一個單字節(jié)的前綴,后面跟著列表中各元素項的RLP編碼,這個前綴的值是0xc0加上列表的總長度。編碼的第一個字節(jié)的取值范圍是[0xc0, 0xf7]。
  5. 如果一個列表的總長度大于55字節(jié),它的RLP編碼包含一個單字節(jié)的前綴,后面跟著列表的長度,后面再跟著列表中各元素項的RLP編碼,這個前綴的值是0xf7加上列表總長度的二進制形式的字節(jié)長度。編碼的第一個字節(jié)的取值范圍是[0xf8, 0xff]。

RLP編碼例子

字符串 "dog" = [0x83, 'd', 'o', 'g' ] (規(guī)則二)

列表 ["cat","dog"] = [0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ] (規(guī)則四)

空字符串 "" = 0x80 (規(guī)則二)

空列表 [] = [0xc0] (規(guī)則四)

整數(shù) 15('\x0f') = 0x0f (規(guī)則一)

整數(shù) 1024('\x04\00') = [0x82, 0x04, 0x00] (規(guī)則二)

列表 [ [], [[]], [ [], [[]] ] ] = [0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0] (規(guī)則四)

字符串 "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = [0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't'] (規(guī)則三)

為什么又要造輪子

對象序列化方法有很多種,常見的像JSON編碼,但是JSON有個明顯的缺點:編碼結果比較大。例如有如下的結構:

type Student struct{
   Name string `json:"name"`
   Sex string `json:"sex"`
}
s := Student{Name:"icattlecoder",Sex:"male"}
bs,_ := json.Marsal(&s)
print(string(bs))
// {"name":"icattlecoder","sex":"male"}

變量s序列化的結果是{"name":"icattlecoder","sex":"male"},字符串長度35,實際有效數(shù)據(jù)是icattlecoder 和male,共計16個字節(jié),我們可以看到JSON的序列化時引入了太多的冗余信息。假設以太坊采用JSON來序列化,那么本來50GB的區(qū)塊鏈可能現(xiàn)在就要100GB,當然實際沒這么簡單。

所以,以太坊需要設計一種結果更小的編碼方法。

RLP編碼定義

RLP實際只給以下兩種類型數(shù)據(jù)編碼:

1. byte數(shù)組

2. byte數(shù)組的數(shù)組,稱之為列表

規(guī)則1:對于值在[0, 127]之間的單個字節(jié),其編碼是其本身。

例1:a的編碼是97。

規(guī)則2:如果byte數(shù)組長度l <= 55,編碼的結果是數(shù)組本身,再加上128+l作為前綴。

例2:空字符串編碼是128,即128 = 128 + 0。

例3:abc編碼結果是131 97 98 99,其中131=128+len("abc"),97 98 99依次是a b c。


規(guī)則3:如果數(shù)組長度大于55, 編碼結果第一個是183加數(shù)組長度的編碼的長度,然后是數(shù)組長度的本身的編碼,最后是byte數(shù)組的編碼。

請把上面的規(guī)則多讀幾篇,特別是數(shù)組長度的編碼的長度。

例4:編碼下面這段字符串:

The length of this sentence is more than 55 bytes, I know it because I pre-designed it

這段字符串共86個字節(jié),而86的編碼只需要一個字節(jié),那就是它自己,因此,編碼的結果如下:

184 86 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前三個字節(jié)的計算方式如下:

184 = 183 + 1,因為數(shù)組長度86編碼后僅占用一個字節(jié)。

86即數(shù)組長度86

84是T的編碼

例5:編碼一個重復1024次"a"的字符串,其結果為:185 4 0 97 97 97 97 97 97 ...。

1024按 big endian編碼為0 0 4 0,省略掉前面的零,長度為2(我的理解:1024(10000000000)需要用到2個字節(jié)),因此185 = 183 + 2。

規(guī)則1~3定義了byte數(shù)組的編碼方案,下面介紹列表的編碼規(guī)則。在此之前,我們先定義列表長度是指子列表編碼后的長度之和。

規(guī)則4:如果列表長度小于55,編碼結果第一位是192加列表長度的編碼的長度,然后依次連接各子列表的編碼。

注意規(guī)則4本身是遞歸定義的。

例6:["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。

規(guī)則5:如果列表長度超過55,編碼結果第一位是247加列表長度的編碼長度,然后是列表長度本身的編碼,最后依次連接各子列表的編碼。

規(guī)則5本身也是遞歸定義的,和規(guī)則3相似。

例7:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

的編碼結果是:

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前兩個字節(jié)的計算方式如下:

248 = 247 +1

88 = 86 + 2

在規(guī)則3的示例中,長度為86,而在此例中,由于有兩個子字符串,每個子字符串本身的長度的編碼各占1字節(jié),因此總共占2字節(jié)。
第3個字節(jié)179依據(jù)規(guī)則2得出179 = 128 + 51
第55個字節(jié)163同樣依據(jù)規(guī)則2得出163 = 128 + 35

例8:最后我們再來看個稍復雜點的例子以加深理解遞歸長度前綴,

["abc",["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]]

編碼結果是:

248 94 131 97 98 99 248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

列表第一項字符串a(chǎn)bc根據(jù)規(guī)則2,編碼結果為131 97 98 99,長度為4。
列表第二項也是一個列表項:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

根據(jù)規(guī)則5,結果為

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

長度為90,因此,整個列表的編碼結果第二位是90 + 4 = 94, 占用1個字節(jié),第一位247 + 1 = 248

以上5條就是RPL的全部編碼規(guī)則。

語言實現(xiàn)

各語言在具體實現(xiàn)RLP編碼時,首先需要將對像映射成byte數(shù)組或列表兩種形式。以go語言編碼struct為例,會將其映射為列表,例如Student這個對象處理成列表["icattlecoder","male"]

type Student struct{
   Name string
   Sex string
}
s := Student{Name:"icattlecoder",Sex:"male"}
buff := bytes.Buffer{}
rpl.Encode(&buff, &s)
print(buff.Bytes())
// [210 140 105 99 97 116 116 108 101 99 111 100 101 114 132 109 97 108 101]

如果編碼map類型,可以采用以下列表形式:

[["",""],["",""],["",""]]

RLP解碼

解碼時,首先根據(jù)編碼結果第一個字節(jié)f的大小,執(zhí)行以下的規(guī)則判斷:

1. 如果f∈ [0,128), 那么它是一個字節(jié)本身。

2. 如果f∈[128,184),那么它是一個長度不超過55的byte數(shù)組,數(shù)組的長度為 l=f-128

3. 如果f∈[184,192),那么它是一個長度超過55的數(shù)組,長度本身的編碼長度ll=f-183,然后從第二個字節(jié)開始讀取長度為ll的bytes,按照BigEndian編碼成整數(shù)l,l即為數(shù)組的長度。

4. 如果f∈(192,247],那么它是一個編碼后總長度不超過55的列表,列表長度為l=f-192。遞歸使用規(guī)則1~4進行解碼。

5. 如果f∈(247,256],那么它是編碼后長度大于55的列表,其長度本身的編碼長度ll=f-247,然后從第二個字節(jié)讀取長度為ll的bytes,按BigEndian編碼成整數(shù)l,l即為子列表長度。然后遞歸根據(jù)解碼規(guī)則進行解碼。

以上解釋了什么叫遞歸長度前綴編碼,這個名字本身很好的解釋了編碼規(guī)則。

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

新聞名稱:RLP編碼介紹-創(chuàng)新互聯(lián)
分享鏈接:http://www.chinadenli.net/article22/dhcgjc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供虛擬主機網(wǎng)站建設網(wǎng)站改版標簽優(yōu)化ChatGPT網(wǎng)站營銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設公司