发一个C#程序:bt种子生成器
2007-11-07 11:47
337 查看
原创文章,未赋予转载复制的权利。如需转载,请联系博主
简要说明:
bt种子torrent文件就是对文件二进制值的sha1
hash,然后按照bencode的格式进行保存。
bencode包含以下的几个类:
IBenCode的定义如下:
interface IBenCode
{
byte[] ToByteArray();
}
规定了所有bencode类型都要提供的功能,用来把内存中的bencode dom转换成字节序列写入文件。
另外,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和优化建议
简要说明:
bt种子torrent文件就是对文件二进制值的sha1
hash,然后按照bencode的格式进行保存。
bencode包含以下的几个类:
IBenCode的定义如下:
interface IBenCode
{
byte[] ToByteArray();
}
规定了所有bencode类型都要提供的功能,用来把内存中的bencode dom转换成字节序列写入文件。
另外,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和优化建议
相关文章推荐
- 使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
- 使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器]
- 如何用C#做一个悬浮窗口程序
- 在WinCE下使用C#来打开一个外部程序
- C#调用参数为函数指针的API函数 - 以SetUnhandledExceptionFilter为例编写一个全局异常处理程序
- 推荐一个非常好的C#的开源Wiki程序Perspective
- c#实现一个程序在一台电脑上只运行一个实例
- c#里面如何激活一个外部程序进程并显示在最前
- 一个有关皇后问题的程序(C#)
- C# 多个程序实例只允许一个及进程间通信sendMessage
- 使用C#编写的一个定时关机程序
- 总结下今天将一个程序转为windows服务(用C#)
- C# 不用IDE 创建一个简单的Window窗口程序
- 多线程编程答案篇(C#和Java):解决pull和push模式在同一个程序中的冲突
- C# 编写Windows服务实现开机启动一个程序
- c# 一个托盘程序的详细设计过程(用户登录)
- 如何构造一个C#语言的爬虫程序
- 解决C#程序只允许运行一个实例的几种方法详解
- 一个演示多线程操作及同步的C#程序
- 将一个C#(快速识图)程序改为Java