イーサー坊RLPコード
5108 ワード
RLP符号化
原文@icattlecoder 以太坊ソース学習—RLPコード
RLP(Recursive Length Prefix)再帰長プレフィックス符号化は、主にイーサ坊におけるデータのネットワーク伝送および永続化ストレージに用いられる.
メリット
JSONより省スペースで、JSONは冗長情報を符号化しすぎて、以下の有用な情報はjoy
とmale
しかありませんtype Student struct {
Name string `json:"name"`
Sex string `json:"sex"`
}
s := Student{"joy", "male"}
marshal, _ := json.Marshal(s)
fmt.Println(string(marshal))
//{"name":"joy","sex":"male"}
コーディング規則
RLPは、実際には2つのタイプのデータのみを符号化する.
type Student struct {
Name string `json:"name"`
Sex string `json:"sex"`
}
s := Student{"joy", "male"}
marshal, _ := json.Marshal(s)
fmt.Println(string(marshal))
//{"name":"joy","sex":"male"}
ルール1
値が[0127]の間の
シングルバイト、エンコード自体
例1:aの符号化は
97
ルール2
byte配列長l<=55の場合、符号化の結果、接頭辞(l+128)、加算群自体
例2:空文字列符号化
128
、すなわち128+0例3:abcの符号化は
131 97 98 99
,プレフィックスは128+3,後はabcの符号化ルール3
byte配列の長さl>55の場合、接頭辞は(長さlの符号化の長さ)+183、次いで配列長の符号化、次いでbyte配列の符号化である
例4:次の文字列を符号化する
The length of this sentence is more than 55 bytes, I know it because I pre-designed it
文字列長l=86、86の符号化は1バイトしか必要ないので、
接頭辞は183+1=
184
そしてlの符号化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
例5:「a」を1024回繰り返す文字列を符号化する文字列の長さは1024で、長さの符号化は0 x 0400で、2バイトを占有するので、
接頭辞は183+2=
185
次に長さコード4 0
そして長い列aの符号化97 97 97 ...
ルール4
リスト長が55未満の場合、接頭辞は192+リストの各要素の長さの合計であり、各サブリスト(再帰定義)を順次リンクします.
例6:符号化リスト[abc,edf]
「abc」の場合、長さは55未満、接頭辞は128+3=
131
、次いでabcの符号化であり、合計4バイトである.「edf」の場合、符号化
131 97 98 99
も4バイトであるリストの全長は8であるため、プレフィックスは192+8=
131 100 101 102
であるため、完全な符号化は200
であるルール5
リスト要素の合計長さが55を超える場合、接頭辞は247+(長さ符号化の長さ)、次いで長さ符号化、次いで各要素の符号化(再帰定義)である.
例7:符号化
200 131 97 98 99 131 100 101 102
最初の要素の長さは51で、リストではありません.適用規則3で、その接頭辞は128+51=["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]
で、それからこの文字の本来の符号化で、その長さは52バイトです.2番目の要素接頭辞は128+35=
179
で、その長さは36バイトです.したがって、リスト全体の長さは88バイトであり、55より大きく、リスト全体について、そのプレフィックスは247+1である(長さ86は1バイトを占有する)=
163
次に長さの符号化248
次に各要素の符号化最終的なエンコーディング結果は次のとおりです.
88
例8:以下は複雑で、理解を深め、符号化する.
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
1番目の要素の符号化は
["abc",["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]]
であり、全長は131 97 98 99
バイトである.2番目の要素の1番目の要素の符号化は
4
であり、そのプレフィックスは128+51=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
であり、符号化後の長さは52である.2番目の要素の2番目の要素の符号化は
179
であり、そのプレフィックスは128+35=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
であり、符号化後の長さは36バイトである.2番目の要素はリストであり、そのサブ要素の全長は52+36=88バイトであり、55より大きく、適用ルール5は、プレフィックスが247+1(88が1バイトを占有する)=
163
であり、次いで長さ符号化248
であり、次いで2番目のサブ要素の符号化の順であるため、2番目の要素符号化後の全長は1(プレフィックス248符号化が1バイトを占有する)+1(長さ88符号化が1バイトを占有する)+88=88
であるしたがって、リスト全体の各サブエレメントの全長は4(第1のエレメント)+90(第2のエレメント)=
90
であり、全体としては、247+1(長さ94が1バイトを占める)=94
、次いで長さ符号248
、次いで各エレメント符号化の順であり、最終的な符号化結果は以下の通りである.94
デコードルール
byte配列の最初の要素を復号する必要がある値vに基づいて判断する
言語実装
各言語はRLP符号化を実現するには、まずオブジェクトをbyte配列またはリスト(byte配列の配列)にマッピングする必要があり、go言語符号化で上述したStudioオブジェクト(structタイプ)を例にとると、リストに処理された結果は
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
であり、最終的にRLP符号化は"[joy", "male"]
であるmapタイプの場合、リストとして処理される形式は次のとおりです.
[203 131 106 111 121 134 102 101 109 97 108 101]
エーテル坊はmapタイプコードをサポートしていないようです