Fixed rlp encoding

This commit is contained in:
obscuren 2013-12-28 15:17:26 +01:00
parent bb8afba20a
commit 95d877f701
2 changed files with 32 additions and 1 deletions

12
rlp.go
View File

@ -41,25 +41,34 @@ func FromBin(data []byte) uint64 {
} }
func Decode(data []byte, pos int) (interface{}, int) { func Decode(data []byte, pos int) (interface{}, int) {
if pos > len(data)-1 {
panic(fmt.Sprintf("index out of range %d for data %q, l = %d", pos, data, len(data)))
}
char := int(data[pos]) char := int(data[pos])
slice := make([]interface{}, 0) slice := make([]interface{}, 0)
switch { switch {
case char < 24: case char < 24:
return data[pos], pos + 1 return data[pos], pos + 1
case char < 56: case char < 56:
b := int(data[pos]) - 23 b := int(data[pos]) - 23
return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b
case char < 64: case char < 64:
b := int(data[pos]) - 55 b := int(data[pos]) - 55
b2 := int(FromBin(data[pos+1 : pos+1+b])) b2 := int(FromBin(data[pos+1 : pos+1+b]))
return FromBin(data[pos+1+b : pos+1+b+b2]), pos+1+b+b2 return FromBin(data[pos+1+b : pos+1+b+b2]), pos+1+b+b2
case char < 120: case char < 120:
b := int(data[pos]) - 64 b := int(data[pos]) - 64
return data[pos+1:pos+1+b], pos+1+b return data[pos+1:pos+1+b], pos+1+b
case char < 128: case char < 128:
b := int(data[pos]) - 119 b := int(data[pos]) - 119
b2 := int(FromBin(data[pos+1 : pos+1+b])) b2 := int(FromBin(data[pos+1 : pos+1+b]))
return data[pos+1+b : pos+1+b+b2], pos+1+b+b2 return data[pos+1+b : pos+1+b+b2], pos+1+b+b2
case char < 184: case char < 184:
b := int(data[pos]) - 128 b := int(data[pos]) - 128
pos++ pos++
@ -70,6 +79,7 @@ func Decode(data []byte, pos int) (interface{}, int) {
slice = append(slice, obj) slice = append(slice, obj)
} }
return slice, pos return slice, pos
case char < 192: case char < 192:
b := int(data[pos]) - 183 b := int(data[pos]) - 183
//b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable) //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable)
@ -122,7 +132,7 @@ func Encode(object interface{}) []byte {
case []byte: case []byte:
// Cast the byte slice to a string // Cast the byte slice to a string
buff.Write(Encode(string(t))) //buff.Write(Encode(string(t)))
case []interface{}, []string: case []interface{}, []string:
// Inline function for writing the slice header // Inline function for writing the slice header

View File

@ -27,6 +27,27 @@ func TestEncode(t *testing.T) {
fmt.Printf("raw: %v encoded: %q == %v\n", dec, slice, strs) fmt.Printf("raw: %v encoded: %q == %v\n", dec, slice, strs)
} }
func TestMultiEncode(t *testing.T) {
inter := []interface{}{
[]interface{}{
"1","2","3",
},
[]string{
"string",
"string2",
"\x86A0J1234567890A\x00B20A0\x82F395843F657986",
"\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360",
},
"test",
}
bytes := Encode(inter)
fmt.Printf("%q\n", bytes)
dec, _ := Decode(bytes, 0)
fmt.Println(dec)
}
func BenchmarkEncodeDecode(b *testing.B) { func BenchmarkEncodeDecode(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
bytes := Encode([]string{"dog", "god", "cat"}) bytes := Encode([]string{"dog", "god", "cat"})