C# 解析torrent文件
基础知识:
torrent文件信息存储格式:
bencoding是一种以简洁格式指定和组织数据的方法。支持下列类型:字节串、整数、列表和字典。
1 字符串存储格式: <字符串的长度>:<字符串的内容>
例如: 4:abcd 表示abcd, 2:ab 表示ab
2 数字的存储格式: i<整数>e
例如: i32e 表示整数32, i1024e 表示整数1024
3 列表的存储格式: l<子元素>e 其中:子元素可以是字符串,整数,列表和字典,或者是它们的组合体
例如: l4:asdf4:qwere 表示 [ "asdf", "qwer" ]
4 字典的存储格式: d<<key><value><key><value><key><value>...<key><value>>e
其中:key只能是字符串类型,value则可以是字符串,整数,列表和字典,或者是它们的组合体,key和value必须是成对出现的
例如: d3:cow3:moo4:spam4:eggse 表示 { "cow" => "moo", "spam" => "eggs" }
d4:spaml1:a1:bee 表示 { "spam" => [ "a", "b" ] }
d9:publisher3:bob4:spaml1:a1:be5:counti80ee 表示 { "publisher" => "bob", "spam" => [ "a", "b" ], "count" => 80 }
代码:
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Text; 5 using NPOI.OpenXmlFormats.Spreadsheet; 6 using Newtonsoft.Json; 7 8 namespace ConsoleApp 9 { 10 /// <summary> 11 /// Summary description for Class1.-change wdq 12 /// </summary> 13 public class Class1 14 { 15 static void Main(string[] args) 16 { 17 if (args.Length != 1) 18 { 19 Console.WriteLine("请指定torrent文件"); 20 return; 21 } 22 string filename = args[0]; 23 var data = Torrent.DecodeFile(filename); 24 //Console.WriteLine(JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented)); 25 ShowData(data); 26 } 27 28 private static void ShowData(ItemBase data) 29 { 30 if (data.ItemType == ItemType.Dictionary) 31 { 32 foreach (var kv in (data as DictionaryItem).DictionaryData) 33 { 34 switch (kv.Value.ItemType) 35 { 36 case ItemType.Dictionary: 37 Console.WriteLine(kv.Key + ":"); 38 ShowData(kv.Value); 39 break; 40 case ItemType.List: 41 Console.WriteLine(kv.Key + ":"); 42 ShowData(kv.Value); 43 break; 44 case ItemType.String: 45 if (kv.Key == "pieces") 46 { 47 break; 48 } 49 Console.WriteLine(kv.Key + "=" + (kv.Value as StringItem).StringData); 50 break; 51 case ItemType.Number: 52 Console.WriteLine(kv.Key + "=" + (kv.Value as NumberItem).NumberData); 53 break; 54 } 55 } 56 } 57 if (data.ItemType == ItemType.List) 58 { 59 foreach (var i in (data as ListItem).ListData) 60 { 61 switch (i.ItemType) 62 { 63 case ItemType.Dictionary: 64 case ItemType.List: 65 ShowData(i); 66 break; 67 case ItemType.String: 68 Console.WriteLine((i as StringItem).StringData); 69 break; 70 case ItemType.Number: 71 Console.WriteLine((i as NumberItem).NumberData); 72 break; 73 } 74 } 75 } 76 } 77 } 78 79 public class Torrent 80 { 81 public static ItemBase DecodeFile(string filename) 82 { 83 using (var fs = new FileStream(filename, FileMode.Open)) 84 { 85 using (BinaryReader br = new BinaryReader(fs)) 86 { 87 return DecodeData(br); 88 } 89 } 90 } 91 92 private static ItemBase DecodeData(BinaryReader br, Stack<bool> st = null) 93 { 94 var flag = br.PeekChar(); 95 List<byte> ls = new List<byte>(); 96 byte b = 0; 97 switch (flag) 98 { 99 case 'e': 100 br.ReadByte(); 101 return null; 102 case 'l'://列表 103 br.ReadByte(); 104 var itemLs = new ListItem(); 105 ItemBase i = null; 106 if (st == null) 107 { 108 st = new Stack<bool>(); 109 } 110 st.Push(true); 111 do 112 { 113 i = DecodeData(br, new Stack<bool>()); 114 if (i != null) 115 { 116 itemLs.ListData.Add(i); 117 } 118 else 119 { 120 st.Pop(); 121 } 122 } while (st.Count != 0 && br.BaseStream.Position != br.BaseStream.Length); 123 124 return itemLs; 125 case 'd'://字典 126 br.ReadByte(); 127 var itemDic = new DictionaryItem(); 128 var key = DecodeData(br); 129 while (key != null && br.BaseStream.Position != br.BaseStream.Length) 130 { 131 var val = DecodeData(br); 132 itemDic.DictionaryData[(key as StringItem).StringData] = val; 133 key = DecodeData(br); 134 } 135 136 return itemDic; 137 case 'i'://数字 138 br.ReadByte(); 139 b = br.ReadByte(); 140 while (b != 'e') 141 { 142 ls.Add(b); 143 b = br.ReadByte(); 144 } 145 return new NumberItem(long.Parse(Encoding.UTF8.GetString(ls.ToArray()))) { RawBytes = ls.ToArray() }; 146 default://字符串 147 b = br.ReadByte(); 148 while (b != ':') 149 { 150 ls.Add(b); 151 b = br.ReadByte(); 152 } 153 var len = int.Parse(Encoding.UTF8.GetString(ls.ToArray())); 154 var bufStr = br.ReadBytes(len); 155 var data = Encoding.UTF8.GetString(bufStr); 156 return new StringItem(data) { RawBytes = bufStr }; 157 } 158 } 159 } 160 161 public class ItemBase 162 { 163 [JsonIgnore] 164 public ItemType ItemType { get; set; } 165 [JsonIgnore] 166 public byte[] RawBytes { get; set; } 167 } 168 169 public class StringItem : ItemBase 170 { 171 public StringItem(string data) 172 { 173 StringData = data; 174 ItemType = ItemType.String; 175 } 176 public string StringData { get; set; } 177 } 178 public class NumberItem : ItemBase 179 { 180 public NumberItem(long num) 181 { 182 NumberData = num; 183 ItemType = ItemType.Number; 184 } 185 public long NumberData { get; set; } 186 } 187 188 public class ListItem : ItemBase 189 { 190 public ListItem() 191 { 192 ItemType = ItemType.List; 193 } 194 public List<ItemBase> ListData { get; set; } = new List<ItemBase>(); 195 } 196 197 public class DictionaryItem : ItemBase 198 { 199 public DictionaryItem() 200 { 201 ItemType = ItemType.Dictionary; 202 } 203 public Dictionary<string, ItemBase> DictionaryData { get; set; } = new Dictionary<string, ItemBase>(); 204 } 205 206 public enum ItemType 207 { 208 String, Number, List, Dictionary 209 } 210 }
Github地址:https://github.com/a14907/AConsoleAppForFun.git
效果:
转载于:https://www.cnblogs.com/a14907/p/7593299.html
C# 解析torrent文件相关推荐
- php解析torrent文件,PHP基于闭包思想实现的BT(torrent)文件解析工具实例详解
本文实例讲述了PHP基于闭包思想实现的torrent文件解析工具.分享给大家供大家参考,具体如下: PHP对静态词法域的支持有点奇怪,内部匿名函数必须在参数列表后面加上use关键字,显式的说明想要使用 ...
- Python3 解析 torrent 文件
(可直接转到文末下载) 起因: 找资源的时候,在某些网站下载到torrent文件.虽说挺常见的,但是这玩意只能用第三方软件打开,总觉得不爽.另外也是单纯出于好奇心,想看看这玩意长什么样子,一探究竟. ...
- Azureus源码剖析(二) ---解析Torrent种子文件
BT种子文件使用了一种叫bencoding的编码方法来保存数据. bencoding有四种类型的数据:srings(字符串),integers(整数),lists(列表),dictionaries(字 ...
- torrent文件解析器
第二步工作是解析torrent文件,有了bencoding编码解析器 解析torrent文件当然是易如反掌的任务了. 实现的封装类CTorrentParser,完成的主要任务有: 1.判断torren ...
- Torrent文件的解析与转换
阅读目录 Torrent简介 Torrent结构 Torrent文件编码 Torrent文件解析 Torrent文件与Magnet 具体实现 Reference 回到顶部 Torrent简介 BitT ...
- C#读取Torrent文件中的可下载文件信息
Torrent文件采用BEncode编码方式(详细介绍见参考文献6),为了读取Torrent文件中的文件信息,需要解析Torrent文件并获取每个文件的详细路径和名称. 在GitHub中查找T ...
- python解析torrent文件库:pytorrent
pytorrent是一个非常小巧的用来解析解析torrent文件python库.核心代码不足150行,却能够完备地解析torrent文件,并支持导出修改后的torrent文件. 使用演示: impor ...
- torrent文件分析
torrent文件信息存储格式: bencoding是一种以简洁格式指定和组织数据的方法.支持下列类型:字节串.整数.列表和字典. 1 字符串存储格式: <字符串的长度>:<字符串 ...
- torrent文件打开成php,.torrent格式用什么打开
.torrent格式用迅雷打开,.torrent种子文件本质上是文本文件,包含Tracker信息和文件信息两部分,Tracker信息主要是BT下载中需要用到的Tracker服务器的地址和针对Track ...
最新文章
- 兼容性—IE6/7下带有overflow:hidden属性的父级元素包不住带有position:relative属性的子元素...
- 五年磨砺:微软Vista开发过程全记录
- 大数据、云计算构筑百姓安全防护网
- C# 获取鼠标相对当前窗口坐标的方法
- C语言获取某个文件中一行内容中指定字符串后的值
- 【Vue】—异步组件
- 蓝桥杯 ADV-155 算法提高 上帝造题五分钟
- mmdetection水下海鲜目标检测
- Linux可执行文件
- linux创建deamon
- mysql outer apply_使用 CROSS APPLY 与 OUTER APPLY 连接查询
- 宁宛 机器人_忠犬机器人3
- 非标自动化设备设计制造的13个步骤 || 技巧总结
- echo和narcissus寓意_希腊神话故事(一)Echo 和 Narcissus
- 可靠数据传输(rdt)实现的底层原理
- 免费视频转文字-音频转文字软件:网易见外工作台, Speechnotes, autosub, Speech to Text, 百度语音识别
- 计算机系统中所有实际物理装置的,计算机系统中所有实际物理装置的总称是计算机________件...
- 保护眼睛的屏幕设置 Win2008R2中的Win7桌面效果设置
- anaconda图形界面打开方式
- Java中有些好的特性(一):静态导入
热门文章
- 工作站HP电脑系统的重装
- OleDbDataAdapter 类
- 美国12月ISM制造业PMI回落 现货金1800关口徘徊交投
- 2022/07/13、14 day06/07:网络编程
- 基于真实需求的新DeFi项目:Stoploss,Overlay,Unipeer,Crescendo
- 2021年保研预推免经验贴
- 从零开始在window10系统下mysql5.7安装审计插件(亲测绝对可用)
- 音视频问题汇总--播放器seekto功能优化
- 人头识别与计数_基于人头检测的行人计数方法技术
- dcom配置计算机下没有,Win7 DCOM配置中我的电脑出现红色箭头,dcom没有属性显示的解决方法...