|
-
Apr 8th, 2004, 12:36 AM
#1
Thread Starter
Lively Member
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.
-
Apr 9th, 2004, 02:41 AM
#2
Thread Starter
Lively Member
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
-
Apr 10th, 2004, 06:26 PM
#3
I wonder how many charact
First, lets format this so its more readble...
Second, review my comment inside the code below..
VB 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
[b]'kT3: The below function does not have a return statement?[/b]
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
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|