-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbdecode.py
59 lines (51 loc) · 1.17 KB
/
bdecode.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
def bdecode(seq):
p = 0
v = seq[p]
assert v in do_map, E_INVSEQ
p, part = do_map[v](seq, p)
return part
def decode_str(seq, p):
i_colon = seq.find(':', p)
str_len = int(seq[p:i_colon])
p = i_colon + str_len + 1
part = seq[i_colon+1:p]
return p, part
def decode_int(seq, p):
p += 1
part = ''
while seq[p] != 'e':
part += seq[p]
p += 1
p += 1
return p, int(part)
def decode_list(seq, p):
part = list()
p += 1
while seq[p] != 'e':
v = seq[p]
assert v in do_map, E_INVSEQ
p, element = do_map[v](seq, p)
part.append(element)
p += 1
return p, part
def decode_dict(seq, p):
part = dict()
p += 1
while seq[p] != 'e':
v = seq[p]
assert v.isdigit(), E_INVSEQ
p, key = decode_str(seq, p)
v = seq[p]
assert v in do_map, E_INVSEQ
p, value = do_map[v](seq, p)
part[key] = value
p += 1
return p, part
# decode_x(seq, p) -> p, x
do_map = dict()
for x in range(10):
do_map[str(x)] = decode_str
do_map['i'] = decode_int
do_map['l'] = decode_list
do_map['d'] = decode_dict
E_INVSEQ = 'Invalid sequence.'