From d92e1ba840ea7791956340f1d2c5b7dedb6d322c Mon Sep 17 00:00:00 2001 From: Darren 'Tadgy' Austin Date: Sun, 27 Sep 2026 20:06:01 +0100 Subject: [PATCH] Add bencode.py, required by torrent2magnet.py. --- bencode.py | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100755 bencode.py diff --git a/bencode.py b/bencode.py new file mode 100755 index 0000000..b5b1df9 --- /dev/null +++ b/bencode.py @@ -0,0 +1,109 @@ +#! /usr/bin/python3 + +import collections + +def bencode(elem): + if type(elem) == str: + elem = str.encode(elem) + + if type(elem) == bytes: + result = str.encode(str(len(elem)))+b":"+elem + elif type(elem) == int: + result = str.encode("i"+str(elem)+"e") + elif type(elem) == list: + result = b"l" + for item in elem: + result += bencode(item) + result += b"e" + elif type(elem) in [dict, collections.OrderedDict]: + result = b"d" + for key in elem: + result += bencode(key)+bencode(elem[key]) + result += b"e" + return result + +def bdecode(bytestr, recursiveCall=False): + startingChars = dict({ + b"i" : int, + b":" : str, + b"l" : list, + b"d" : dict + }) + digits = [b"0", b"1", b"2", b"3", b"4", b"5", b"6", b"7", b"8", b"9"] + + started = ended = False + curtype = None + + numstring = b"" # for str, int + result = None # for list, dict + key = None # for dict + + while len(bytestr) > 0: + # reading and popping from the beginning + char = bytestr[:1] + + if not started: + + bytestr = bytestr[1:] + + if char in digits: + numstring += char + + elif char in startingChars: + + started = True + curtype = startingChars[char] + + if curtype == str: + size = int(bytes.decode(numstring)) + # try to decode strings + try: + result = bytes.decode(bytestr[:size]) + except UnicodeDecodeError: + result = bytestr[:size] + bytestr = bytestr[size:] + ended = True + break + + elif curtype == list: + result = [] + + elif curtype == dict: + result = collections.OrderedDict() + else: + raise ValueError("Expected starting char, got ‘"+bytes.decode(char)+"’") + + else: # if started + + if not char == b"e": + + if curtype == int: + bytestr = bytestr[1:] + numstring += char + + elif curtype == list: + item, bytestr = bdecode(bytestr, recursiveCall=True) + result.append(item) + + elif curtype == dict: + + if key == None: + key, bytestr = bdecode(bytestr, recursiveCall=True) + + else: + result[key], bytestr = bdecode(bytestr, recursiveCall=True) + key = None + + else: # ending: char == b"e" + bytestr = bytestr[1:] + if curtype == int: + result = int(bytes.decode(numstring)) + ended = True + break + if ended: + if recursiveCall: + return result, bytestr + else: + return result + else: + raise ValueError("String ended unexpectedly")