krusen / bencodenet Goto Github PK
View Code? Open in Web Editor NEW.NET library for encoding/decoding bencode and reading/writing torrent files
License: The Unlicense
.NET library for encoding/decoding bencode and reading/writing torrent files
License: The Unlicense
If I need to create torrent object:
var trackers = new List<IList<string>>()
{
new List<string>()
{
"TRACKER.URL"
}
};
var torrent = new Torrent()
{
CreationDate = DateTime.Now,
IsPrivate = true,
Trackers = trackers,
PieceSize = 524288,
File = new SingleFileInfo
{
FileSize = file.Length,
FileName = file.Name
}
};
and then after calculating hashes write it to a file:
torrent.EncodeTo(torrentFile);
then 'announce' field of a torrent will be a list and torrent clients won't recognize tracker URL
NOTE: I have no idea what's in this torrent or whether it's malicious, it's one from a recent large dump.
This should probably throw an InvalidTorrentException
instead. qBittorrent loads it fine fwiw
Dim tor As BencodeNET.Objects.BDictionary
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fs As FileStream = File.OpenRead("C:\Users\servet\Desktop\torr.torrent")
tor = BencodeNET.Bencode.DecodeDictionary(fs)
Debug.Print(tor.GetHashCode())
End Sub
I tried this code and it returned "7588182".
But orginally .torrent hash code : magnet:?xt=urn:btih:cd57f0bd9f898ab9e229a2e25a7bef123b064942&dn=torr.mkv
actually: cd57f0bd9f898ab9e229a2e25a7bef123b064942
I'm using v2.1.0.
var parser = new BencodeParser();
var torrent = parser.Parse<Torrent>("Files\\ubuntu-14.10-desktop-amd64.iso.torrent");
string pieces = torrent.Pieces;
int piecesLength = pieces.Length;
System.Diagnostics.Debug.WriteLine($"piecesLength = {piecesLength}");
torrent.Pieces.length must be 44380, but returns 42014.
ubuntu-14.10-desktop-amd64.iso.torrent
is same as those in the BencodeNET.Tests.
would be nice to have a method that would allow us to get filesize, name, hash from a magnet link. Magnet handling in general. or maybe magent to torrent would be enough as for torrents there are already methods.
I compared BencodeNET with quite some libraries to parse a whole lot of torrents. While mostly Bencode delivers the best results in some cases other libraries worked better when decoding paths and filenames. As it turns out MonoTorrent for example seems to prefer the "name.utf-8" and "path.utf-8" entries (if present!) over their non-"utf-8" counterparts.
Knowing that Bencode primarily wasn't meant as a torrent library: Is there any chance that this behaviour will be implemented in BencodeNET?
The GetMagnetLink recalculates the InfoHash, but the recalculated InfoHash is different from the OriginalInfoHash that was calculated on initial loading of the file, and so the magnet has a different urn.
The torrent is from https://archive.org/details/equestriagirlsdashforthecrown and is https://archive.org/download/equestriagirlsdashforthecrown/equestriagirlsdashforthecrown_archive.torrent (but I have the same problem with other torrents).
I'm using .NET Core 7.0
var parser = new BencodeParser();
Torrent torrent = parser.Parse<Torrent>("equestriagirlsdashforthecrown_archive.torrent");
string magnetLink1 = torrent.GetMagnetLink();
The result I obtain:
magnet:?xt=urn:btih:d02d19163df7ab5c835d84f0a0b1f9bd4c32d239&dn=equestriagirlsdashforthecrown&tr=http%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce&tr=http%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce
The expected result:
magnet:?xt=urn:btih:91d66f363d2f603e336b34493d10fe63f7740251&dn=equestriagirlsdashforthecrown&tr=http%3a%2f%2fbt1.archive.org%3a6969%2fannounce&tr=http%3a%2f%2fbt2.archive.org%3a6969%2fannounce&ws=http%3a%2f%2fia802702.us.archive.org%2f18%2fitems%2f&ws=http%3a%2f%2fia902702.us.archive.org%2f18%2fitems%2f&ws=https%3a%2f%2farchive.org%2fdownload%2f
OriginalInfoHash is (correctly) 91d66f363d2f603e336b34493d10fe63f7740251
(or something similar, BencodeNET doesn't support url-lists/ws= , but it isn't a problem. It is a feature used only by very few servers like archive.org)
Although BencodeNET actually supports multiple encodings, when loading a non utf-8 encoded torrent, the process while parsing such as ToString
in the ParseSingleFileInfo
function, Does not use the encoding provided in the torrent but using the default utf-8 encoding to convert the BString
to string
. After that, there is a process to set the encoding to each field, but the string has been lost some data irreversible.
Another point, all fields in ExtraFields
are not properly marked as given encoded, so that they are marked as utf-8.
The sample has uploaded.
GBK.torrent.zip
Hello, I installed BencodeNET 1.3.1 via nuget on .net core, and I got an error about compatible.
C:\Program Files\dotnet\dotnet.exe restore "F:\c#\asdf.vs\restore.dg"
log : Restoring packages for F:\c#\asdf\src\asdf\project.json...
error: Package BencodeNET 1.3.1 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package BencodeNET 1.3.1 supports:
error: - net35 (.NETFramework,Version=v3.5)
error: - net40 (.NETFramework,Version=v4.0)
error: - net45 (.NETFramework,Version=v4.5)
error: One or more packages are incompatible with .NETCoreApp,Version=v1.0.
log : Writing lock file to disk. Path: F:\c#\asdf\src\asdf\project.lock.json
log : F:\c#\asdf\src\asdf\asdf.xproj
log : Restore failed in 553ms.
Errors in F:\c#\asdf\src\asdf\asdf.xproj
Package BencodeNET 1.3.1 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package BencodeNET 1.3.1 supports:
- net35 (.NETFramework,Version=v3.5)
- net40 (.NETFramework,Version=v4.0)
- net45 (.NETFramework,Version=v4.5)
One or more packages are incompatible with .NETCoreApp,Version=v1.0.
Anything can fix that?
Thanks.
Minor issue in your case, but you might want to consider fixing this. SHA1 is not thread safe if it not declared as public static.
I had issues with sha1 but I was using it under really high loads for piece hash validation and I came across this issue.
You could just declared your sha1 (in TorrentUtil.cs) to ensure thread-safety, like this:-
public static SHA1 sha1 = new SHA1Managed();
Is multi torrent file size going to be implemented or is there a workaround to get the filesize of multi-torrents? thanks. Edit: nevermind I just didnt see there was a method for it. my bad
fastresume in the bt_backup directory records the metadata information of the torrent file.
Hi, I'm now working on an implementation for .NET Core Tracker server, and since there's some important performance enhancement in .NET Core 2.2 (or .NET Standard 2.1), is there any plan to support them?
Some known memory acceleation manner in .NET Core 2.2 includes:
Maybe the parsing system should make some API changes in order to support them.
Best regards,
Can this library generate a torrent file from a Magnet link? I noticed it can go the other way.
any chance you could add support to parse .torrent.loaded files as well?
they have a lot of the same info as a .torrent file but in a slightly different format.
Parsing a specific torrent file fails with ArgumentOutOfRangeException:
System.ArgumentOutOfRangeException: Value to add was out of range.
Parameter name: value
at System.DateTime.Add(Double value, Int32 scale)
at BencodeNET.Objects.BNumber.op_Implicit(BNumber number)
at BencodeNET.Parsing.TorrentParser.CreateTorrent(BDictionary data)
at BencodeNET.Parsing.BencodeParser.Parse[T](BencodeStream stream)
at BencodeNET.Parsing.BencodeParser.Parse[T](Byte[] bytes)
qbittorent opens file without any errors or warnings.
Please find the torrent file in question attached.
I am using your code but it seems while creating torrent, calculating and adding pieces is not implemented yet? or maybe Im wrong, I had to calculate and add pieces manually, I mean isn't really a method to pass a folder name and it adds files and pieces for you?
Decoding takes about double the time compared to https://github.com/CreateChen/Bencode
However we are a bit more strict when parsing than the mentioned library.
I've got a torrent file that has both "length" and "files" fields in the info dictionary.
I do realise that it's a clear violation of BEP3 that states:
There is also a key length or a key files, but not both or neither.
But unfortunately torrents like that do exist and qBittorrent opens then without errors or warnings.
If you don't want to ignore this error in torrent's metadata, how about adding a "forgiving" parser option?
Please find the example of malformed torrent in the attachment.
the demo code:
Torrent torrent = new BencodeParser().Parse("C:\111.torrent");
BencodeNET.Exceptions.BencodeException:“Missing parser for the type 'BencodeNET.Torrents.Torrent'. Stream position: 0
Any plans on providing first class support for parsing torrent files?
Just like BList.AsStrings()
just for BNumber
=> long
Should return IEnumerable<long>
I've been unsuccessful at reading out the tracker info in a torrent file. Debugging torrent.Trackers shows me a count of 1 but no matter what I do I cannot get the value. How do I get the Tracker info out?
torrent[TorrentFields.Announce] gives me errors and looping Trackers with another loop gives me nothing.
I've searched the interwebs and haven't found any answers there. I hope I can get an answer here.
Hi
Thank for your great job ! Very usefull and well documented
I'm writing a tool able to replace trackers in a list of torrent files. But I've found an issue when there is only one tracker defined. AnnouceList is not set. I understand that could be logical but client torrent (as qbittoorent) don't use Announce but AnnounceList. In this case, no tracker are detected by the torrent client.
I've changed locally with trackerCount > 0) for AnnouceList.
Best regards
Tracker.cs
if (trackerCount > 0)
torrent[TorrentFields.Announce] = ...
if (trackerCount > 1)
torrent[TorrentFields.AnnounceList] = ...
how can i get the torrent's folder? :|
torrent.Path and FullPath only leave the filenames :(
I would like to get only the folder what torrent created from
Hi,
First, I'd like to say thanks for the great work. I want to add/edit the "comment" item with this code
using (var stream = File.OpenRead(TorrentFile))
{
var torrent = Bencode.DecodeTorrentFile(stream);
torrent.Comment = "xxx";
using (var ms = new MemoryStream())
{
torrent.EncodeToStream(ms);
multipartFormDataContent.Add(new ByteArrayContent(ms.ToArray()),
'"' + "file_input" + '"',
'"' + _fileName + '"');
}
}
Is it the correct way to add/edit items? Anyone please help me. Thanks a lot.
System.BadImageFormatException
Message : Could not load file or assembly 'System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)
StackTrace : at BencodeNET.Parsing.BStringParser.Parse(BencodeReader reader)
at BencodeNET.Parsing.BDictionaryParser.Parse(BencodeReader reader)
at BencodeNET.Torrents.TorrentParser.Parse(BencodeReader reader)
at BencodeNET.Parsing.BencodeParserExtensions.Parse[T](IBencodeParser parser, Stream stream)
at BencodeNET.Parsing.BencodeParserExtensions.Parse[T](IBencodeParser parser, String filePath)
at MultiUploader.Helpers.Files.ReadTorrentFiles(String torrentPath)
System.BadImageFormatException
Message : Cannot load a reference assembly for execution.
Can you help me? :/
Hi,
I am trying to get the infohash string from this file:
TestFile.zip
I know that correct info hash of this file is 037e4ddf1e84fe4d4290fd40c442af2201750849 but when I call to TorrentUtil.CalculateInfoHash this returns 42DCB1CBA3ADD25D1498D2FA8F84DA46EC944BFB that is an incorrect value.
This is an example of code I am using:
var bencodeParser = new BencodeParser();
var stream = File.OpenRead("Test.torrent");
var torrentFileData = bencodeParser.Parse<Torrent>(stream);
var infoHash = TorrentUtil.CalculateInfoHash(torrentFileData);
//Expected value is 037e4ddf1e84fe4d4290fd40c442af2201750849
I am using bencodeNET over netcoreapp1.1
var parser = new BencodeParser();
var torrent = parser.Parse<Torrent>(torrentFile);
i use above codes to parse torrent files. It works ok for most files, but fails for some while there's an exception thrown from Parse
method as below
System.InvalidCastException: Not all elements are of type 'BencodeNET.Objects.BList'. --->
System.InvalidCastException: Unable to cast object of type 'BencodeNET.Objects.BString' to type 'BencodeNET.Objects.BList'.
at System.Linq.Enumerable.CastIterator[TResult](IEnumerable source)+MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at BencodeNET.Objects.BList`1..ctor(IEnumerable`1 objects)
at BencodeNET.Objects.BList.AsType[T]() --- End of inner exception stack trace ---
at BencodeNET.Objects.BList.AsType[T]()
at BencodeNET.Parsing.TorrentParser.ParseTrackers(BDictionary data, Encoding encoding) at BencodeNET.Parsing.TorrentParser.CreateTorrent(BDictionary data)
at BencodeNET.Parsing.TorrentParser.Parse(BencodeStream stream)
at BencodeNET.Parsing.BencodeParser.Parse[T](Stream stream)
at BencodeNET.Parsing.BencodeParser.Parse[T](String filePath)
at
i've tried convert those failed torrent files to magnetic links on some sites( eg: http://www.torrent2magnet.com/) , there's no exception reported by those sites.
the version of BencodeNET i used is version 2.3.0.
the attachment is a torrent file which causes the exception:
Bumblebee 2018 BluRay 1080p AVC Atmos TrueHD7.1 (2).torrent.zip
I have
var file = @"C:\....\test.torrent";
var parser = new BencodeParser();
Torrent torrent = parser.Parse<Torrent>(file);
torrent.Comment = "";
torrent.CreatedBy = "";
torrent.CreationDate = DateTime.Now;
torrent.IsPrivate = true;
var list = new List<IList<string>>();
list.Add(new List<string> { "https://mytracker.org" });
torrent.Trackers = list;
How to save back to test.torrent
file ?
Hi there, first of all I'd like to thank you for taking the time to create such an awesome tool. After looking at a few examples I came to the conclusion that I can't really figure it out myself.
I'd like to get the stream url from either a torrent or preferably a magnet link. How would one achieve this?
Thanks in advance,
Kajirinn.
Add methods to encode and decode from byte array directly without using a stream first
I have a bencode string and I want to convert it to a C# class obj.
But I found BObject's ctor is internal, and IBObject interface is too complex.
By only allowing the library to decode a stream or a string, it is very limited. I have a nice MessageRecieved
method that provides a byte[] message, IPEndPoint source
and I am unable to make use of the library as I provide the raw message from the UdpClient
. It would be nice to see an additional overload that can Decode the provided message.
The same goes for the following code:
public void FindNode(IPEndPoint endPoint)
{
var data = new BDictionary()
{
{"t", "aa"},
{"y", "q"},
{"q", "find_node"},
{
"a",
new BList()
{
new BString(NodeId)
}
}
};
using (MemoryStream ms = new MemoryStream())
{
data.EncodeToStream(ms);
_udp.SendAsync(ms.ToArray(), endPoint);
Console.WriteLine($"[FindNode] Sending to {endPoint.Address}");
}
}
It would be nice to have a function such as data.GetBytes()
;
I do have some torrents where the calculated NumberOfPieces
property differs from the actual number of pieces Pieces.Length / 20
.
An example:
TotalSize
= 4034584869PieceSize
= 524288NumberOfPieces
= 7696 (int)Math.Ceiling((double)TotalSize / PieceSize)
The length of the Pieces
array is 154120, hence the actual number of pieces - at least the ones we have checksums for - is 154120 / 20 = 7706.
This is not really a bug because the torrent itself seems to be inconsistent. However it might be a good idea to check this if the torrent is parsed with TorrentParserMode.Strict
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.