Skip to content

Instantly share code, notes, and snippets.

@khubo
Created September 25, 2024 06:42
Show Gist options
  • Save khubo/c12df9e8f78f18bf3633d72cb00bb4d3 to your computer and use it in GitHub Desktop.
Save khubo/c12df9e8f78f18bf3633d72cb00bb4d3 to your computer and use it in GitHub Desktop.
basic bencode decoder
class Decode:
def __init__(self, content: bytes):
pass
self.content = content
self.current_pos = 0
self.data = {}
def current(self) -> int:
return self.content[self.current_pos]
def next(self) -> int | None:
if self.current_pos < len(self.content) - 1:
self.current_pos += 1
return self.content[self.current_pos]
else:
return None
# the parse methods follow
def parse_dict(self):
result = {}
# should always be a key value pair
# key will be a string
# value can be anything.
self.next()
try:
while self.current() != ord('e'):
key = self.parse_bytes()
value = self.parse_function(self.current())()
result[key.decode()] = value
self.next()
return result
except Exception as e:
print(e)
raise Exception("invalid character while parsing the dict")
def parse_list(self):
ch = self.next()
values = []
while ch and ch != ord('e'):
values.append(self.parse_function(ch)())
ch = self.current()
self.next()
return values
def parse_int(self):
next_ch = self.next()
number = ""
while next_ch and next_ch != ord('e'):
number += chr(next_ch)
next_ch = self.next()
self.next()
return int(number)
def parse_bytes(self):
num_bytes = chr(self.current())
while self.next() != ord(':'):
num_bytes += chr(self.current())
self.next()
byte_string = b""
for _ in range(int(num_bytes)):
byte_string += chr(self.current()).encode()
self.next()
return byte_string
def parse_function(self, a: int):
if a == ord('d'):
return self.parse_dict
if a == ord('l'):
return self.parse_list
if a == ord('i'):
return self.parse_int
if a >= ord('0') and a <= ord('9'):
return self.parse_bytes
raise Exception('invalid delimeter')
def parse_content(self):
"""
method that parse the content of byte string.
"""
current_ch = self.current()
result = self.parse_function(current_ch)()
self.data = result
return self.data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment