73 lines
2.3 KiB
Haxe
73 lines
2.3 KiB
Haxe
package leenkx.network.torrent;
|
|
|
|
import haxe.io.Bytes;
|
|
|
|
class TorrentInfo {
|
|
|
|
public static inline var PEERID_PREFIX = "-LX0001-";
|
|
public static inline var PEERID_LENGTH = 20;
|
|
public static inline var HASH_LENGTH = 20;
|
|
public static inline var MIN_PIECE_LENGTH = 16384;
|
|
|
|
public static function pieceLength(size:Int):Int {
|
|
var scaled = size < 1024 ? 1.0 : size / 1024;
|
|
var exp = Std.int(Math.log(scaled) / Math.log(2) + 0.5);
|
|
if (exp < 0) exp = 0;
|
|
if (exp > 30) exp = 30;
|
|
var len = 1 << exp;
|
|
return len > MIN_PIECE_LENGTH ? len : MIN_PIECE_LENGTH;
|
|
}
|
|
|
|
public static function pieces(content:Bytes, plen:Int):Bytes {
|
|
var count = content.length == 0 ? 0 : Math.ceil(content.length / plen);
|
|
var out = Bytes.alloc(count * HASH_LENGTH);
|
|
for (i in 0...count) {
|
|
var off = i * plen;
|
|
var len = content.length - off;
|
|
if (len > plen) len = plen;
|
|
var sha = haxe.crypto.Sha1.make(content.sub(off, len));
|
|
out.blit(i * HASH_LENGTH, sha, 0, HASH_LENGTH);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
public static function infoDict(name:String, content:Bytes):Dynamic {
|
|
var plen = pieceLength(content.length);
|
|
var info:Dynamic = {};
|
|
Reflect.setField(info, "length", content.length);
|
|
Reflect.setField(info, "name", name);
|
|
Reflect.setField(info, "piece length", plen);
|
|
Reflect.setField(info, "pieces", pieces(content, plen));
|
|
return info;
|
|
}
|
|
|
|
public static function infoHash(name:String, content:Bytes):Bytes {
|
|
return haxe.crypto.Sha1.make(Bencode.encode(infoDict(name, content)));
|
|
}
|
|
|
|
public static function identifierHash(identifier:String):Bytes {
|
|
return infoHash(identifier, Bytes.ofString(identifier));
|
|
}
|
|
|
|
public static function peerId():Bytes {
|
|
var prefix = Bytes.ofString(PEERID_PREFIX);
|
|
var random = Bytes.ofString(Crypto.toHex(Crypto.randomBytes(6)));
|
|
var out = Bytes.alloc(PEERID_LENGTH);
|
|
out.blit(0, prefix, 0, prefix.length);
|
|
out.blit(prefix.length, random, 0, PEERID_LENGTH - prefix.length);
|
|
return out;
|
|
}
|
|
|
|
public static function toBinaryString(bytes:Bytes):String {
|
|
var sb = new StringBuf();
|
|
for (i in 0...bytes.length) sb.addChar(bytes.get(i));
|
|
return sb.toString();
|
|
}
|
|
|
|
public static function fromBinaryString(str:String):Bytes {
|
|
var bytes = Bytes.alloc(str.length);
|
|
for (i in 0...str.length) bytes.set(i, str.charCodeAt(i) & 0xFF);
|
|
return bytes;
|
|
}
|
|
}
|