Skip to content

Commit c723b84

Browse files
committed
Bencoded dictionary keys are in lexicographical order
1 parent 14d95d7 commit c723b84

File tree

4 files changed

+13
-21
lines changed

4 files changed

+13
-21
lines changed

README.md

-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ func main() {
3030
}
3131
```
3232

33-
If a specific order is desired for dictionary keys when generating a bencode string, specify the keys in desired order in the dictionary key "\_\_keys". For dictionaries generated from bencode.Decode, "\_\_keys" is already set to the order the keys were read from the file. Example:
34-
```go
35-
dict["__keys"] = []string{"int key", "string key"}
36-
```
37-
3833
### Decode
3934
bencode.Decode takes an io.Reader as argument and returns (map[string]interface{}, error). Example:
4035
```go

decoder.go

-4
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ func (decoder *decoder) readString() (string, error) {
107107

108108
func (decoder *decoder) readDictionary() (map[string]interface{}, error) {
109109
dict := make(map[string]interface{})
110-
keys := []string{}
111110
for {
112111
key, err := decoder.readString()
113112
if err != nil {
@@ -145,15 +144,12 @@ func (decoder *decoder) readDictionary() (map[string]interface{}, error) {
145144
return nil, err
146145
}
147146

148-
keys = append(keys, key)
149147
if nextByte == 'e' {
150148
break
151149
} else if err := decoder.UnreadByte(); err != nil {
152150
return nil, err
153151
}
154152
}
155-
156-
dict["__keys"] = keys
157153
return dict, nil
158154
}
159155

encoder.go

+13-10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ package bencode
2525
import (
2626
"bytes"
2727
"strconv"
28+
"sort"
2829
)
2930

3031
type encoder struct {
@@ -87,17 +88,19 @@ func (encoder *encoder) writeList(list []interface{}) {
8788
}
8889

8990
func (encoder *encoder) writeDictionary(dict map[string]interface{}) {
91+
// Sort in lexicographical order
92+
list := make(sort.StringSlice, len(dict))
93+
i := 0
94+
for key, _ := range dict {
95+
list[i] = key
96+
i++
97+
}
98+
list.Sort()
99+
90100
encoder.WriteByte('d')
91-
if keys, ok := dict["__keys"]; ok {
92-
for _, v := range keys.([]string) {
93-
encoder.writeString(v) // Key
94-
encoder.writeInterfaceType(dict[v]) // Value
95-
}
96-
} else {
97-
for k, v := range dict {
98-
encoder.writeString(k) // Key
99-
encoder.writeInterfaceType(v) // Value
100-
}
101+
for _, key := range list {
102+
encoder.writeString(key) // Key
103+
encoder.writeInterfaceType(dict[key]) // Value
101104
}
102105
encoder.WriteByte('e')
103106
}

encoder_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030

3131
func TestEncodeSinglefileTorrentBencode(t *testing.T) {
3232
dict := make(map[string]interface{})
33-
dict["__keys"] = []string{"announce", "comment", "creation date", "httpseeds", "info"}
3433
dict["announce"] = "http://bttracker.debian.org:6969/announce"
3534
dict["comment"] = "\"Debian CD from cdimage.debian.org\""
3635
dict["creation date"] = 1391870037
@@ -40,7 +39,6 @@ func TestEncodeSinglefileTorrentBencode(t *testing.T) {
4039
}
4140

4241
infoDict := make(map[string]interface{})
43-
infoDict["__keys"] = []string{"length", "name", "piece length", "pieces"}
4442
infoDict["length"] = 232783872
4543
infoDict["name"] = "debian-7.4.0-amd64-netinst.iso"
4644
infoDict["piece length"] = 262144

0 commit comments

Comments
 (0)