发一个C#程序:bt种子生成器
简要说明:
bt种子torrent文件就是对文件二进制值的sha1 hash,然后按照bencode的格式进行保存。
bencode包含以下的几个类:
IBenCode的定义如下:
interface IBenCode
{
byte[] ToByteArray();
}
另外,bencode中有些string是可显示的,有compare的需求,有些是用来存储二进制的,比如hash值。所以我做了两个类来实现目标:
BenBinaryFormString, BenStringFormString。其中两个类都需要实现IBenCode接口的ToByteArray方法,为避免代码重复,我把共同的内容提取到了抽象类中:
abstract class BenByteString : IBenCode
{
abstract protected
byte[] GetByteArray();
public byte[]
ToByteArray()
{
List<byte>
byteList = new List<byte>();
byte[] byteContent = GetByteArray();
string sizeHeader =
string.Format("{0}:", byteContent.Length);
byteList.AddRange(Encoding.UTF8.GetBytes(sizeHeader));
byteList.AddRange(byteContent);
return byteList.ToArray();
}
}
torrent文件生成过程是:
1. 构建bencode dom
2. 按照一个固定大小比如1M读取二进制块
3. 计算出sha1 hash
4. 把bencode dom写入文件
下面的CreateTorrentFile实现了这个流程:(包括了两大步骤,DOM的生成和文件写入)
private static void
CreateTorrentFile(string[] fileName,
string announceUrl,
string torrentFileName,
string torrentDirectoryName)
{
string[] sortedFileName = Utility.OrdinalSortStringArray(fileName);
// 1. create the torrent tree
BenCode.BenDictionary root = new
BenCode.BenDictionary();
// 1.1 announce URL
root.Add("announce",new
BenCode.BenStringFormString(announceUrl));
// 1.2 info block
BenCode.BenDictionary info = new
BenCode.BenDictionary();
// 1.2.1 name
bool IsDirectory = !string.IsNullOrEmpty(torrentDirectoryName);
string
strNameValue;
if (IsDirectory)
{
strNameValue = torrentDirectoryName;
}
else
{
strNameValue = Path.GetFileName(sortedFileName[0]);
}
BenCode.BenStringFormString
nameValue =
new BenCode.BenStringFormString(strNameValue);
info.Add("name", nameValue);
// 1.2.2 piece length
BenCode.BenInt pieceLength = new
BenCode.BenInt(1024 * 1024);
info.Add("piece
length", pieceLength);
// 1.2.3 pieces
BenCode.BenBinaryFormString pieces =
new BenCode.BenBinaryFormString(Get1MBasedHashFromFiles(sortedFileName));
info.Add("pieces", pieces);
// 1.2.4 single file
if (IsDirectory)
{
BenCode.BenList files = GetFilesBlock(sortedFileName);
info.Add("files",
files);
}
else
{
BenCode.BenInt length =
new
BenCode.BenInt(
Utility.GetFileLength(sortedFileName[0])
);
info.Add("length",
length);
}
root.Add("info", info);
// 2. write to the file
using (FileStream
torrentFileStream = new FileStream(torrentFileName,
FileMode.Create,
FileAccess.Write))
{
byte[] torrentFileByte
= root.ToByteArray();
torrentFileStream.Write(torrentFileByte,
0, torrentFileByte.Length);
}
}
源程序下载地址:下载,欢迎提供bug和优化建议