-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbencode.py
More file actions
115 lines (91 loc) · 3.09 KB
/
Copy pathbencode.py
File metadata and controls
115 lines (91 loc) · 3.09 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
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
104
105
106
107
108
109
110
111
112
113
114
115
from collections import OrderedDict
class Decoder:
TOKEN_INT='i'
TOKEN_LIST='l'
TOKEN_DICT='d'
TOKEN_END='e'
TOKEN_STR=':'
def __init__(self,data:bytes):
if not isinstance(data,bytes):
raise TypeError('You stupid ni')
self.data=data
self.index=0
def decode(self):
c = self.data[self.index]
if c == ord(self.TOKEN_DICT):
return self._decode_dict()
elif c == ord(self.TOKEN_LIST):
return self._decode_list()
elif c == ord(self.TOKEN_INT):
return self._decode_int()
elif 48<=c<=57 :
return self._decode_string()
def _decode_dict(self):
dct=OrderedDict()
self.index+=1
while self.data[self.index]!=ord(self.TOKEN_END):
key=self.decode()
value=self.decode()
dct[key]=value
self.index+=1
return dct
def _decode_list(self):
lst=[]
self.index +=1
while self.data[self.index]!=ord(self.TOKEN_END):
lst.append(self.decode())
self.index +=1
return lst
def _decode_int(self):
save=self.index
while self.data[self.index] != ord(self.TOKEN_END):
self.index=self.index + 1
self.index=self.index+1
return int(self.data[save + 1 : self.index-1].decode())
def _decode_string(self):
save=self.index
while self.data[self.index]!=ord(self.TOKEN_STR):
self.index=self.index + 1
str_len=int(self.data[save:self.index].decode())
self.index=self.index + 1
self.index=self.index+str_len
return self.data[self.index-str_len:self.index]
class Encoder:
TOKEN_INT='i'
TOKEN_LIST='l'
TOKEN_DICT='d'
TOKEN_END='e'
TOKEN_STR=':'
def __init__(self,data):
self.data=data
def encode(self):
if isinstance(self.data,dict):
return self._encode_dict()
elif isinstance(self.data,list):
return self._encode_list()
elif isinstance(self.data,int):
return self._encode_int()
elif isinstance(self.data,str):
return self._encode_string()
elif isinstance(self.data,bytes):
return self._encode_bytes()
else :raise(TypeError('You stupid ni'))
def _encode_dict(self):
result=bytearray(b'd')
for e in self.data:
result+=Encoder(e).encode()
result+=Encoder(self.data[e]).encode()
result+=b'e'
return bytes(result)
def _encode_list(self):
result=bytearray(b'l')
for e in self.data:
result+=Encoder(e).encode()
result+=b'e'
return bytes(result)
def _encode_int(self):
return str.encode(self.TOKEN_INT+str(self.data)+self.TOKEN_END)
def _encode_string(self):
return str(len(self.data)).encode()+self.TOKEN_STR.encode()+self.data.encode()
def _encode_bytes(self):
return (str(len(self.data))+self.TOKEN_STR+str(self.data)).encode()