-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathbencoding.py
More file actions
67 lines (63 loc) · 2.02 KB
/
bencoding.py
File metadata and controls
67 lines (63 loc) · 2.02 KB
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
"""Helper methods to encode and decode Bencoding data."""
def _decode(raw_buffer, elements, index=0):
if raw_buffer[index] == ord('d'):
index += 1
obj = {}
while raw_buffer[index] != ord('e'):
key = []
value = []
index = _decode(raw_buffer, key, index)
index = _decode(raw_buffer, value, index)
obj[key[0]] = value[0]
index += 1
elements.append(obj)
elif raw_buffer[index] == ord('l'):
index += 1
list_elements = []
while raw_buffer[index] != ord('e'):
value = []
index = _decode(raw_buffer, value, index)
list_elements.append(value[0])
index += 1
elements.append(list_elements)
elif raw_buffer[index] == ord('i'):
index += 1
pos = index + raw_buffer[index:].find(ord('e'))
number = int(raw_buffer[index:pos])
index = pos+1
elements.append(number)
else:
pos = index + raw_buffer[index:].find(ord(':'))
size = int(raw_buffer[index:pos])
index = pos+1
data = raw_buffer[index:index+size]
index += size
elements.append(data)
return index
def decode(raw_buffer):
"""Decode a bytes string into its corresponding data via Bencoding."""
elements = []
_decode(raw_buffer, elements)
return elements[0]
def encode(data):
"""Encode data into a bytes string via Bencoding."""
if isinstance(data, bytes):
return str(len(data)).encode("ascii") + b':' + data
elif isinstance(data, str):
return encode(data.encode("ascii"))
elif isinstance(data, int):
return b'i' + str(data).encode("ascii") + b'e'
elif isinstance(data, list):
result = b'l'
for d in data:
result += encode(d)
result += b'e'
return result
elif isinstance(data, dict):
result = b'd'
for key, value in data.items():
result += encode(key)
result += encode(value)
result += b'e'
return result
raise ValueError("Unexpected bencode_encode() data")