Jump to content
LoranRendel

Torrent (bencode) UDF

Recommended Posts

LoranRendel

Hello,

This is my UDF working with *.torrent files.

It converts torrent file to readable and editable text structure and back to torrent.

Binary data will be encoded in base64.

Written on pure AutoIt, except base64 located

Due to limitation of this version of base64 code, code will not work on x64 compilation.

Updated to new x64 compatible code.

This code can also be used to edit utorrent/BitTorrent config files (like settings.dat), as it encoded using bencode.

Examples are included.

torrentUDF.zip

Edited by xrewndel

Share this post


Link to post
Share on other sites
wraithdu

Look here for x64 compatible machine code functions.

  • Like 1

Share this post


Link to post
Share on other sites
LoranRendel

Look here for x64 compatible machine code functions.

Thanks. I have updated the archive.

Share this post


Link to post
Share on other sites
garbb

Thanks for making this, I was having trouble working with torrent files in autoit until I found this thread.

I modified your _Torrent_Parse function slightly to add outputting of the infohash for a torrent file because I had a need to do this:

#include <Crypt.au3>

Func _Torrent_Parse($File)
    Local $Data, $Binary, $hFile, $Byte, $Number, $String, $Size, $infodictlevel, $recording_info_bytes=false, $infobytes
    $hFile = FileOpen($File, 16)
    If @error Then Return SetError(1, 0, '')
    While True
        $Byte = BinaryToString(FileRead($hFile, 1))
        if $recording_info_bytes then $infobytes &= $Byte
        If @error Then ExitLoop
        Switch $Byte
            Case 'd'; Dictionary ->
                $Data &= __Torrents_StringFormat('Dictionary')
                __Torrents_Level(1)
                if $string='info' then
                    $infodictlevel=__Torrents_Level()
                    $recording_info_bytes = true
                    $infobytes = $Byte
                EndIf
            Case 'l'; List ->
                $Data &= __Torrents_StringFormat('List')
                __Torrents_Level(1)
            Case 'i'; Integer
                $Number = ''
                Do
                    $Number &= $Byte
                    $Byte = BinaryToString(FileRead($hFile, 1))
                    if $recording_info_bytes then $infobytes &= $Byte
                    If @error Then ExitLoop
                Until $Byte = 'e'
                VarTrim($Number, 1)
                Switch $String
                    Case 'length', 'piece length'
                        If $Number < 2 ^ 20 Then
                            $Number &= ' (' & Round($Number / 2 ^ 10, 3) & ' KiB)'
                        ElseIf $Number >= 2 ^ 20 And $Number < 2 ^ 30 Then
                            $Number &= ' (' & Round($Number / 2 ^ 20, 3) & ' MiB)'
                        Else
                            $Number &= ' (' & Round($Number / 2 ^ 30, 3) & ' GiB)'
                        EndIf
                    Case 'creation date'
                        $Number &= ' (' & _DateAdd('s', $Number, "1970/01/01 00:00:00") & ')'
                EndSwitch
                $Data &= __Torrents_StringFormat('integer: ' & $Number)
            Case 'e'; End of element <-
                __Torrents_Level(-1)
                if __Torrents_Level()=$infodictlevel-1 then $recording_info_bytes = false
                $Data &= __Torrents_StringFormat('End')
            Case '0' To '9'; String's size
                $Size &= $Byte
            Case ':'; String
                $String = BinaryToString(FileRead($hFile, $Size))
                if $recording_info_bytes then $infobytes &= $String
                $Size = ''
                If StringInStr($String, @LF) or StringInStr($String, @CR) Then
                    $Data &= __Torrents_StringFormat('binary: ' & _Base64Encode(StringToBinary($String), 0))
                Else
                    $Data &= __Torrents_StringFormat('string: ' & $String)
                EndIf
            Case Else; Error
                Return SetError(2, 0, '')
        EndSwitch
    WEnd
    Local $bHash = _Crypt_HashData($infobytes, $CALG_SHA1)
    $Data &= @CRLF& 'Infohash: '&StringTrimLeft($bHash,2)
    Return StringAddCR($Data)
EndFunc   ;==>_Torrent_Parse
Edited by garbb

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • ludocus
      By ludocus
      Hi Guys,
      I'm trying to create a program that'll download .torrent files for me automatically and place them in a folder so uTorrent starts downloading them.
      The whole script works flawless (for now) except for the most important part: Downloading the .torrent file.
      It works, it downloads the .torrent file perfectly, but for some reason uTorrent gives me the error that 'the torrent file was not correctly encoded'.
      For some reason downloading the torrent with InetGet instead of my browser, fucks it up. The size of the torrent is exactly the same as that of the one I download with my browser, still the files are different.
      This is my script:
       
      #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.8.1 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <INet.au3> #include <Array.au3> $downloadfolder = 'C:\Users\Ludo\Downloads\torrents' $searchquiry = StringReplace('the hobbit desolation of smaug', ' ', '+') $preferedsite = 'kickmirror' $link = 'http://torrentz.eu/search?f='&$searchquiry $source = _INetGetSource($link, True) $S1 = StringSplit($source, '<a rel="nofollow" href="/searchA?f='&$searchquiry&'"> date </a> | <a rel="nofollow" href="/searchS?f='&$searchquiry&'"> size </a> | <b> peers </b></h3>', 1) $S2 = StringSplit($S1[2], '<dl><dt style="text-align: right">', 1) $S3 = StringSplit($S2[1], @LF, 1) global $torrents[$S3[0]+1][7] $torrents[0][0] = $S3[0]-1 ; Form of $torrents[a][b] for b: ; $torrents[a][0] = total string ; $torrents[a][1] = torrent url ; $torrents[a][2] = torrent title ; $torrents[a][3] = torrent size ; $torrents[a][4] = torrent seeders ; $torrents[a][5] = torrent peers ; $torrents[a][6] = torrent type For $i = 1 to $torrents[0][0] ;MsgBox(0, '', _StringBetw($S3[$i], '<a href="', '">')) $torrents[$i][0] = $S3[$i] $torrents[$i][1] = _StringBetw($S3[$i], '<a href="', '">') $torrents[$i][2] = _StringStrip(_StringBetw($S3[$i], '<a href="'&$torrents[$i][1]&'">', '</a>')) $temp1 = StringSplit($S3[$i], '</a> &#187; ', 1) $temp2 = StringSplit($temp1[2], '</dt><dd>', 1) $temp3 = StringSplit($S3[$i], '</span></span><span class="s">', 1) $temp4 = StringSplit($temp3[2], '</span> <span class="u">', 1) $temp5 = StringSplit($temp4[2], '</span><span class="d">', 1) $temp6 = StringSplit($temp5[2], '</span>', 1) $torrents[$i][3] = $temp4[1] $torrents[$i][4] = $temp5[1] $torrents[$i][5] = $temp6[1] $torrents[$i][6] = $temp2[1] Next ;_ArrayDisplay($torrents) ;ClipPut($torrents[1][1]&@CRLF&@CRLF&$torrents[$torrents[0][0]][2]) $source2 = _INetGetSource('http://torrentz.eu/'&$torrents[1][1]) $A1 = StringSplit($source2, ' torrent download locations</h2><dl><dt>', 1) $A2 = StringSplit($A1[1], '</span> ', 1) $A3 = StringSplit($A1[2], '<a href="', 1) $locations = $A2[$A2[0]] global $tors[$locations+1] $n = 0 For $i = 2 to $locations $A4 = StringSplit($A3[$i], '" ', 1) $tors[$i] = $A4[1] If StringInstr($tors[$i], $preferedsite) Then $n = $i EndIf Next If $n = 0 Then Msgbox(32, 'Too bad', 'No kickmirror torrent links found..') Exit EndIf ;_ArrayDisplay($tors) $source3 = _INetGetSource($tors[$n], True) ;$B1 = _StringBetw($source3, '<a title="Magnet link" href="', '"') ;ShellExecute($B1) $B1 = _StringBetw($source3, '<a rel="nofollow" title="Download verified torrent file" href="', '"') $B2 = StringSplit($B1, '.torrent?title=', 1) $finallink = $B2[1]&'.torrent' InetGet($finallink,$downloadfolder&'\'&$B2[2]&'.torrent', 4) MsgBox(32, 'Succes', 'Torrent started downloading!') Func _StringBetw($string, $start, $end) $pa = StringSplit($string, $start, 1) If $pa[0] < 2 Then Return 0 $pb = StringSplit($pa[2], $end, 1) Return $pb[1] EndFunc Func _StringStrip($string) $s = StringReplace($string, '<b>', '') $s1 = StringReplace($s, '</b>', '') Return $s1 EndFunc Please try it out, then try to run the torrent with utorrent or some other torrent downloader.
      If somebody knows what the problem is, I'd be very happy if you'd help me here!
      Thnx in advance,
      Ludo
    • Decipher
      By Decipher
      This is a Torrent Browser that should only be used to download legal torrents. It helps you to look up and download movie trailers. It should never be used to download copyrighted material. It is an awesome program that any torrent downloader will absolutely love. Neither the AutoIt community nor anyone associated with AutoIt condones to the misuse of this program. Don't do it! That being said download your copy while you can!

      Before you download this program you must read this first:
      U.S. Copyright Infringement and Remedies or Understandable Version

      I suggest everyone read this just for informational purposes:
      RIAA, MPAA Copyright Warnings: Facts and Fiction

      There are plenty of legal torrent and therfore justification for this program.

      Legal Torrents:
      *Games, Music and Software
      * Movies and Videos

      Features:
      Search 30 different torrent websites including The Pirate Bay simultaneously!
      Easy to use movie trailer lookup tool!
      Download torrents with your own set of trackers.
      All your torrent downloading needs in one place there is no need to open your internet browser!

      If you happen to come across what you may think is copyrighted material you should immediately report it! Stopping Copyright Infringement

      The reason I posted this here is of course because I have a question. Will you please allow this autoit created program to be posted on the forums? I and many others realize that there is nothing wrong with this. Pheraps the reasonable authority here would consider allowing the Autoit community decide by vote?

      The attached is a self extracting archive. The password is "anonymous". To obtain the source run the program from the command line with "extract" as a parameter.
      example: TorrentBrowser.exe -extract or /extract

      If you don't want this post to be censored then post your thoughts on the matter.

      Download Torrent Browser Now!

      Please do not just delete this post without letting us all know why like it was done before with a similiar topic. I would suggest removing the link instead if whoever needs time to make a decision. Thanks.
    • Decipher
      By Decipher
      I would like to programmatically check to see if a given tracker has information on the torrent I specify. This requires that the SHA-1 Info Hash of a torrent be encoded to make valid requests. I read from: http://nakkaya.com/2009/12/03/bittorrent-tracker-protocol/ If you don't pay attention to the spec and send this directly to tracker you will get an error this should be in URL Encoded form. Padding every two chars with % sign also doesn't work, been there done that don't waste your time. Any hex in the hash that corresponds to a unreserved character should be replaced,
      a-z A-Z 0-9 -_.~

      Partition the hex in to chunks of two and check if the hex corresponds to any of these values, if they do replace them with the unreserved char.

      So that a hash such as,
      123456789abcdef123456789abcdef123456789a

      becomes,
      %124Vx%9a%bc%de%f1%23Eg%89%ab%cd%ef%124Vx%9a

      notice that hex 34 became 4 which is what it is in ASCII. You can test the correctness of your hashes using the tracker url but don't request from announce request from file,
      http://some.tracker.com/file?info_hash=hash

      If you get a torrent back that means you have the correct hash.

      I have tried the above and failed. Here's my code:
      $testStr = "123456789abcdef123456789abcdef123456789a" ConsoleWrite(_EncodeHash($testStr) & @CRLF) Func _EncodeHash($sString) If (Not IsString($sString)) Or $sString = "" Then Return SetError(1, 0, 0) Local $aArray = StringRegExp($sString, "(?s).{1," & 2 & "}", 3), $sEncodedHash For $i = 0 To UBound($aArray) -1 If StringInStr($sString, Chr(Dec($aArray[$i]))) Then $sEncodedHash &= Chr(Dec($aArray[$i])) Else $sEncodedHash &= "%" & $aArray[$i] EndIf Next Return $sEncodedHash EndFunc If you follow the first link in my post there is an example but I'm unfamiliar with the language being used. Thanks for any help.
×