a2800276 / bncode Goto Github PK
View Code? Open in Web Editor NEWbencoding (bittorrent) in javascript
License: MIT License
bencoding (bittorrent) in javascript
License: MIT License
According to the specification: https://wiki.theory.org/BitTorrentSpecification#Bencoding
Keys must be strings and appear in sorted order (sorted as raw strings, not alphanumerics).
I didn't see this implemented in your encodeDict
function.
Lines 370 to 372 in 704e8d5
var keys = Object.keys(obj).sort()
This is not the correct way of sorting dictionary entries. The encoder is producing specification-incompliant octets that’ll be floating around in the wild, the network.
When you say “strings” in the context of Bencoding, you mean “binary strings,” or more specifically, “8-bit byte sequences.”
BEP 52 — The BitTorrent protocol specification version 2
Note that, in the context of bencoding, strings, including dictionary keys, are arbitrary byte sequences (
uint8_t[]
).
And Array.prototype.sort
compares 16-bit units by default.
If
compareFn
is not supplied, all non-undefined array elements are sorted by converting them to strings and comparing strings in UTF-16 code units order.
The simple .sort()
results in a different order (sorted_in_utf16
) than the correct one (sorted_in_utf8
). Observe:
const A = String.fromCodePoint(0xFF61);
const B = String.fromCodePoint(0x10002);
const sorted_in_utf8 = [A, B].sort((a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b))); // [A, B]
const sorted_in_utf16 = [A, B].sort(); // [B, A]
Hey, so, I've run into a slight issue with this portion of the doc:
The exception to this is strings appearing as keys in bencoded dicts. These are decoded as Javascript Strings, as they should always be strings of (ascii) characters and if they weren't decoded as JS Strings, dict's couldn't be mapped to Javascript objects.
While this is technically true, it does present a problem. While communicating with a tracker, often times, the infohashes are returned as the dictionary keys. For example, a simple scrape
response:
d5:filesd20:[info_hash]d8:completei23492e10:incompletei4544e10:downloadedi1024eeee
Where [info_hash]
is a 20-byte, binary sha1sum that isn't necessarily well-suited to be a String
. Say we decode that, either using bncode.decode
or new bncode.decoder/decode/result
. We'll get something along the lines of:
{
"files": {
"[incorrect info_hash]": {
"complete": 23492,
"incomplete": 4544,
"downloaded": 1024
}
}
}
Where [incorrect info_hash]
is a String
with length 1. Obviously this is the fault of the String
, but it's a relatively common use-case. Perhaps it might be wise to create a class for a BDict
or something, that allows the use of Buffer
s as keys?
var data = "d5:dict5:valueee"
data = bncode.decode(data);
console.log(data.get(0)); //<Buffer ...> or "value"
console.log(data.key(0)); //<Buffer ...> or "dict"
Obviously this would add complexity to the library, but, I've been butting my head up against this problem for a few weeks now. Any thoughts/suggestions? I'd be more than willing to prepare a pull request with any guidance.
I've tried both making a decor object and using the decor() function directly from the module. And both give me this error on every torrent I tried. I even tried the torrent in the tests folder
https://raw.github.com/a2800276/bencode.js/master/test/test.torrent
I'm reading the files with binary encoding.
I am currently integrating torrent-stream to node-Tor/Peersm.
I don't know for what reason encodeDict is using for (var i in keys) to enumerate the sorted result of Object.keys which is an Array instead of a usual forEach
If you have added properties to Array.prototype (like concatBuffers in my case), then the properties get enumerated too and bncode crashes, I don't want to use proto with enumerable false and setPrototypeOf is not available in all browsers.
So I would suggest to use forEach instead.
It's a bit confusing to have the names differ. It's not a huge deal, just a suggestion. GitHub automatically handles URL redirects for both the website and git remotes if you rename a repo.
Currently we can stream file and decoding it.
Is is possible to implement encoding stream?
I want to do this
var cryptoStream = crypto.createHash('sha1');
cryptoStream.on('end', function(){
console.log(cryptoStream.digest('hex'));
});
var bencStream = new benc.EncodeStream({prop: []});
bencStream.on('data', function(chunk){
cryptoStream.update(chunk);
});
bencStream.on('end', function(){
cryptoStream.update(null);
});
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.