Results 1 to 3 of 3

Thread: BitTorrent Bencode library assistance.

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2004
    Posts
    95

    BitTorrent Bencode library assistance.

    I'm trying to port the Bencode library into VB.NET. If you aren't familiar with what that is, it's the part of the BitTorrent file downloading software that parses a .torrent file to get all the information regarding it.

    Here are the specifications:

    Bencoding is done as follows:

    * Strings are length-prefixed base ten followed by a colon and the string. For example 4:spam corresponds to 'spam'.
    * Integers are represented by an 'i' followed by the number in base 10 followed by an 'e'. For example i3e corresponds to 3 and i-3e corresponds to -3. Integers have no size limitation. i-0e is invalid. All encodings with a leading zero, such as i03e, are invalid, other than i0e, which of course corresponds to 0.
    * Lists are encoded as an 'l' followed by their elements (also bencoded) followed by an 'e'. For example l4:spam4:eggse corresponds to ['spam', 'eggs'].
    * Dictionaries are encoded as a 'd' followed by a list of alternating keys and their corresponding values followed by an 'e'. For example, d3:cow3:moo4:spam4:eggse corresponds to {'cow': 'moo', 'spam': 'eggs'} and d4:spaml1:a1:bee corresponds to {'spam': ['a', 'b']} . Keys must be strings and appear in sorted order (sorted as raw strings, not alphanumerics).


    Here is my source code:

    Public Class m4DBdecode
    Private Result As New ArrayList
    Private Key As New ArrayList
    Private Value As New ArrayList
    Dim Torrent As New Hashtable
    Function decode_int(ByVal x As String, ByVal f As Integer) As ArrayList
    Dim EndAt As Integer = x.IndexOf("e", f)
    Dim IntLength As Integer = (EndAt - f)
    Result.Clear()
    Result.Insert(0, CInt(x.Substring(f, IntLength)))
    Result.Insert(1, x.IndexOf("e", f) + 1)
    Return Result
    End Function
    Function decode_string(ByVal x As String, ByRef f As Integer) As ArrayList
    If x.Length <= f Then
    Exit Function
    End If
    Dim StartAt As Integer = x.IndexOf(":", f) + 1
    Dim Length As Integer = CInt(x.Substring(f, (StartAt - 1) - f))
    Result.Clear()
    Result.Insert(0, x.Substring(StartAt, Length))
    Result.Insert(1, (StartAt + Length))
    Return Result
    End Function
    Function decode_list(ByVal x As String, ByRef f As Integer) As ArrayList
    While x.Substring(f, 1) <> "e"
    Value = bdecode_rec(x, f)
    Torrent.Add(Value(0), System.DBNull.Value)
    f = CType(Value(1), Integer)
    End While
    Result.Clear()
    Result.Insert(0, Torrent)
    Result.Insert(1, f + 1)
    End Function
    Function decode_dict(ByVal x As String, ByRef f As Integer) As ArrayList
    While x.Substring(f) <> "e"
    Key = decode_string(x, f)
    f = CType(Key(1), Integer)
    Dim keyname As String = CType(Key(0), String)
    Value = bdecode_rec(x, f)
    Torrent.Add(keyname, Value(0))
    f = CType(Value(1), Integer)
    End While
    Result.Clear()
    Result.Insert(0, Torrent)
    Result.Insert(1, f + 1)
    Return Result
    End Function
    Function bdecode_rec(ByVal x As String, ByRef f As Integer) As ArrayList
    Dim t As String = x.Substring(f, 1)
    If t = "i" Then
    Return decode_int(x, f + 1)
    ElseIf t = "l" Then
    Return decode_list(x, f + 1)
    ElseIf t = "d" Then
    Return decode_dict(x, f + 1)
    Else : Return decode_string(x, f)
    End If
    End Function
    Function bdecode(ByVal x As String) As ArrayList
    Result.Clear()
    Result = bdecode_rec(x, 0)
    Return Result
    End Function
    End Class

    Please help, this is honestly only my third week ever learning to code in any language. I am excited but frustrated all the same. This code actually works, set some breakpoints in the debugger and you will see it's parsing properly. I only have trouble stopping it when it reaches the end of the file. To see what a .torrent looks like, go to http://www.suprnova.org and download one, and open it up in notepad! Or reply and I will attach one for you.

    AND, I seriously doubt I'm collecting that information right. What's the best way to collect that information in a way that I can use the objects in software? I'm thinking creating a class to define the structure of the .torrent, but due to nesting I'm not sure how to quite implement this, better yet, construct the inherited class from this parser.

    Any kind of help on ANYTHING is kindly appreciated. If you would like me to include the original BitTorrent Python code for this library or even one written in PHP I can do that too. Just hit me back.

    Peace,
    KT

    Edit: I should note this isn't the entire program, obviously. But the function that starts parsing is bdecode(x) where x is the string that's encoded (the data from the .torrent file). To test the code above, you can either create a FileStream and open a .torrent, then read it into the x string variable OR just copy and paste the .torrent into a console, or even just Dim it as x before calling the function.

    I should note that I have not yet tried a complete .torrent with the hashed piece info at the end, I'm going to need to learn how to get the SHA1 hash later.
    Last edited by Kt3; Apr 8th, 2004 at 12:44 AM.

  2. #2

    Thread Starter
    Lively Member
    Join Date
    Apr 2004
    Posts
    95
    Anybody? Since I posted this I've actually improved the code, created a class to define what makes a .torrent file one, and created a new object every time a dictionary was created, to which the entry was appended to an array list. I still can't figure out how to get this code to stop when it reaches the end of the string and return the final result to bdecode(x) then back to the calling function in my main subroutine. Again, I've only been learning to code for 3 weeks so how come no one out there can help?

    KT

  3. #3
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    First, lets format this so its more readble...
    Second, review my comment inside the code below..
    VB Code:
    1. Public Class m4DBdecode
    2.     Private Result As New ArrayList
    3.     Private Key As New ArrayList
    4.     Private Value As New ArrayList
    5.     Dim Torrent As New Hashtable
    6.  
    7.     Function decode_int(ByVal x As String, ByVal f As Integer) As ArrayList
    8.         Dim EndAt As Integer = x.IndexOf("e", f)
    9.         Dim IntLength As Integer = (EndAt - f)
    10.         Result.Clear()
    11.         Result.Insert(0, CInt(x.Substring(f, IntLength)))
    12.         Result.Insert(1, x.IndexOf("e", f) + 1)
    13.         Return Result
    14.     End Function
    15.  
    16.     Function decode_string(ByVal x As String, ByRef f As Integer) As ArrayList
    17.         If x.Length <= f Then
    18.             Exit Function
    19.         End If
    20.  
    21.         Dim StartAt As Integer = x.IndexOf(":", f) + 1
    22.         Dim Length As Integer = CInt(x.Substring(f, (StartAt - 1) - f))
    23.  
    24.         Result.Clear()
    25.         Result.Insert(0, x.Substring(StartAt, Length))
    26.         Result.Insert(1, (StartAt + Length))
    27.  
    28.         Return Result
    29.     End Function
    30.  
    31. [b]'kT3: The below function does not have a return statement?[/b]
    32.     Function decode_list(ByVal x As String, ByRef f As Integer) As ArrayList
    33.         While x.Substring(f, 1) <> "e"
    34.             Value = bdecode_rec(x, f)
    35.             Torrent.Add(Value(0), System.DBNull.Value)
    36.             f = CType(Value(1), Integer)
    37.         End While
    38.         Result.Clear()
    39.         Result.Insert(0, Torrent)
    40.         Result.Insert(1, f + 1)
    41.     End Function
    42.  
    43.  
    44.     Function decode_dict(ByVal x As String, ByRef f As Integer) As ArrayList
    45.         While x.Substring(f) <> "e"
    46.             Key = decode_string(x, f)
    47.             f = CType(Key(1), Integer)
    48.             Dim keyname As String = CType(Key(0), String)
    49.             Value = bdecode_rec(x, f)
    50.             Torrent.Add(keyname, Value(0))
    51.             f = CType(Value(1), Integer)
    52.         End While
    53.         Result.Clear()
    54.         Result.Insert(0, Torrent)
    55.         Result.Insert(1, f + 1)
    56.  
    57.         Return Result
    58.     End Function
    59.  
    60.  
    61.     Function bdecode_rec(ByVal x As String, ByRef f As Integer) As ArrayList
    62.         Dim t As String = x.Substring(f, 1)
    63.         If t = "i" Then
    64.             Return decode_int(x, f + 1)
    65.         ElseIf t = "l" Then
    66.             Return decode_list(x, f + 1)
    67.         ElseIf t = "d" Then
    68.             Return decode_dict(x, f + 1)
    69.         Else : Return decode_string(x, f)
    70.         End If
    71.     End Function
    72.  
    73.     Function bdecode(ByVal x As String) As ArrayList
    74.         Result.Clear()
    75.         Result = bdecode_rec(x, 0)
    76.         Return Result
    77.     End Function
    78.  
    79. End Class
    Last edited by nemaroller; Apr 10th, 2004 at 06:37 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width