Dust8 的博客

读书百遍其义自见

0%

python3实现bencode

把python换成3了,网上的bencode基本不能用了。

因为 types 里已经没了那些类型, 如 IntType等等。

而且python3里只有一种整数类型,不分 intlong了。

所以只好自己改造下。 Bencode编解码的python代码这里有详细的讲解。

大体差不多,一些错误判断就没写了。

下面是我改的, github里是 b.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#! /usr/bin/env python3


def bdecode(x):
try:
r, l = decode_func[x[0]](x, 0)
return r
except (IndexError, KeyError, ValueError):
pass


def decode_int(x, f):
f += 1
newf = x.index("e", f)
n = int(x[f:newf])
return (n, newf+1)


def decode_string(x, f):
coln = x.index(":", f)
n = int(x[f:coln])
coln += 1
return (x[coln:coln+n], coln+n)


def decode_list(x, f):
r,f = [], f+1
while x[f] != "e":
v, f = decode_func[x[f]](x, f)
r.append(v)
return (r, f+1)


def decode_dict(x, f):
r, f = {}, f+1
while x[f] != "e":
k, f = decode_string(x, f)
r[k], f = decode_func[x[f]](x, f)
return (r, f+1)


decode_func = {}
decode_func['l'] = decode_list
decode_func["d"] = decode_dict
decode_func['i'] = decode_int
decode_func['0'] = decode_string
decode_func['1'] = decode_string
decode_func['2'] = decode_string
decode_func['3'] = decode_string
decode_func['4'] = decode_string
decode_func['5'] = decode_string
decode_func['6'] = decode_string
decode_func['7'] = decode_string
decode_func['8'] = decode_string
decode_func['9'] = decode_string


def bencode(x):
r = []
encode_func[type(x)](x, r)
return "".join(r)


def encode_int(x, r):
r.extend(("i", str(x), "e"))


def encode_string(x, r):
r.extend((str(len(x)), ":", x))


def encode_list(x, r):
r.append("l")
for i in x:
print(type(i))
encode_func(type(i))(i, r)
r.append("e")


def encode_dict(x, r):
r.append("d")
ilist = sorted(x.items())
ilist.sort()
for k, v in ilist:
r.extend((str(len(k)), ":", k))
encode_func[type(v)](v, r)
r.append("e")


encode_func = {}
encode_func[type(3)] = encode_int
encode_func[type("")] = encode_string
encode_func[type([])] = encode_list
encode_func[type(())] = encode_list
encode_func[type({})] = encode_dict


if __name__ == "__main__":
e = {"t": "aa", "y": "q", "q": "ping", "a": {"id": "abcdefghij0123456789"}}
d = "d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe"

assert bencode(e) == d
assert bdecode(d) == e