Files
LNXSDK/leenkx/Sources/leenkx/network/torrent/TorrentInfo.hx
2026-10-03 17:40:22 -07:00

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;
}
}