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  乌生鱼汤  阅读(4167)  评论(11编辑  收藏  举报

导航