sailing

Everything...

发一个C#程序:bt种子生成器

原创文章,未赋予转载复制的权利。如需转载,请联系博主

简要说明:
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和优化建议


posted on 2007-11-07 11:47 乌生鱼汤 阅读(1909) 评论(10)  编辑 收藏

评论

#1楼 [楼主] 2007-11-07 13:03 踏雪无痕      

torrent文件我觉得完全可以做成xml文件的方式,而不是reinvent the wheel,发明一个bencode。不过可能当初作者考虑到了xml不能很好的保存二进制内容,于是决定自己做一个了。不过从这里,也可以看出xml的一个弱点:不能保存二进制的值。当然,你可以说base64 encode后再保存到xml里面。遗憾的是二进制转成base64的时候体积膨胀了不少。当想解决一个问题的时候就间接导致了另外一个问题,掉进了一个不断循环的怪圈。(是不是有点像道教的那两条黑白鱼?)
现在想想xml的纯文本结构化存储,漏掉了对二进制值的支持。
当面对这么一盘子要求的时候:结构化存储,纯文本文件,支持二进制值,还真找不到一个完美的办法。   回复  引用  查看    

#2楼  2007-11-07 14:42 oxsoft.cn [未注册用户]

关注中.....   回复  引用    

#3楼  2007-11-07 20:27 luyu [未注册用户]

不知道,有没有可以下载BT文件的C#方面的内容啊。   回复  引用    

#4楼  2007-11-07 21:59 恶猫 [未注册用户]

关注中!!!

欢迎访问小站 http://www.iphone100.com.cn/   回复  引用    

#5楼 [楼主] 2007-11-08 01:38 踏雪无痕      

@luyu
没有做下载部分。

我是参考下面的两个协议做的:
bitcomet的协议:
http://wiki.theory.org/BitTorrentSpecification
bt的官方协议:
http://www.bittorrent.org/protocol.html   回复  引用  查看    

#6楼  2007-11-08 21:51 随心所欲      

收藏这个文章可以么?   回复  引用  查看    

#7楼 [楼主] 2007-11-08 22:12 踏雪无痕      

@随心所欲
收藏自己用可以的,改天我写个common creative。主要是不希望被人复制到垃圾网站去,放到垃圾堆里。   回复  引用  查看    

#8楼  2007-11-09 09:16 随心所欲      

去搜索一下,很多有用的文章都是在垃圾堆里找到的。
那些网站的的搜索结果很靠前,这是好事呢,还是坏事呢。   回复  引用  查看    

#9楼  2007-11-15 11:40 huangdechun [未注册用户]

为什么同一个文件 生成多个种子文件的时候 有时候会出现哈希校验结果不一样的情况啊?   回复  引用    

#10楼 [楼主] 2007-11-15 16:15 踏雪无痕      

同一个文件只能生成相同的种子文件啊。不会产生多个不同的种子文件。   回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-11-07 12:30 编辑过


相关链接:
 

导航

统计

与我联系

搜索

 

我的标签

随笔档案(167)

Asp

Friends

其它链接

最新评论

阅读排行榜