原文地址:http://blog.csdn.net/love_beibei/article/details/7460565

[csharp] view plaincopyprint?
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Collections;
  6. namespace XunleiHelper
  7. {
  8. public class Torrent
  9. {
  10. #region 私有字段
  11. private string _openError = "";
  12. private bool _openFile = false;
  13. private string _announce = "";
  14. private IList<string> _announceList = new List<string>();
  15. private DateTime _createTime = new DateTime(1970, 1, 1, 0, 0, 0);
  16. private long _codePage = 0;
  17. private string _comment = "";
  18. private string _createdBy = "";
  19. private string _encoding = "";
  20. private string _commentUTF8 = "";
  21. private IList<FileInfo> _fileList = new List<FileInfo>();
  22. private string _name = "";
  23. private string _nameUTF8 = "";
  24. private long _pieceLength = 0;
  25. private byte[] _pieces;
  26. private string _publisher = "";
  27. private string _publisherUTF8 = "";
  28. private string _publisherUrl = "";
  29. private string _publisherUrlUTF8 = "";
  30. private IList<string> _notes = new List<string>();
  31. private long _totalLength;
  32. #endregion
  33. #region 属性
  34. /// <summary>
  35. /// 错误信息
  36. /// </summary>
  37. public string OpenError { set { _openError = value; } get { return _openError; } }
  38. /// <summary>
  39. /// 是否正常打开文件
  40. /// </summary>
  41. public bool OpenFile { set { _openFile = value; } get { return _openFile; } }
  42. /// <summary>
  43. /// 服务器的URL(字符串)
  44. /// </summary>
  45. public string Announce { set { _announce = value; } get { return _announce; } }
  46. /// <summary>
  47. /// 备用tracker服务器列表(列表)
  48. /// </summary>
  49. public IList<string> AnnounceList { set { _announceList = value; } get { return _announceList; } }
  50. /// <summary>
  51. /// 种子创建的时间,Unix标准时间格式,从1970 1月1日 00:00:00到创建时间的秒数(整数)
  52. /// </summary>
  53. public DateTime CreateTime { set { _createTime = value; } get { return _createTime; } }
  54. /// <summary>
  55. /// 未知数字CodePage
  56. /// </summary>
  57. public long CodePage { set { _codePage = value; } get { return _codePage; } }
  58. /// <summary>
  59. /// 种子描述
  60. /// </summary>
  61. public string Comment { set { _comment = value; } get { return _comment; } }
  62. /// <summary>
  63. /// 编码方式
  64. /// </summary>
  65. public string CommentUTF8 { set { _commentUTF8 = value; } get { return _commentUTF8; } }
  66. /// <summary>
  67. /// 创建人
  68. /// </summary>
  69. public string CreatedBy { set { _createdBy = value; } get { return _createdBy; } }
  70. /// <summary>
  71. /// 编码方式
  72. /// </summary>
  73. public string Encoding { set { _encoding = value; } get { return _encoding; } }
  74. /// <summary>
  75. /// 文件信息
  76. /// </summary>
  77. public IList<FileInfo> FileList { set { _fileList = value; } get { return _fileList; } }
  78. /// <summary>
  79. /// 种子名
  80. /// </summary>
  81. public string Name { set { _name = value; } get { return _name; } }
  82. /// <summary>
  83. /// 种子名UTF8
  84. /// </summary>
  85. public string NameUTF8 { set { _nameUTF8 = value; } get { return _nameUTF8; } }
  86. /// <summary>
  87. /// 每个块的大小,单位字节(整数)
  88. /// </summary>
  89. public long PieceLength { set { _pieceLength = value; } get { return _pieceLength; } }
  90. /// <summary>
  91. /// 每个块的20个字节的SHA1 Hash的值(二进制格式)
  92. /// </summary>
  93. private byte[] Pieces { set { _pieces = value; } get { return _pieces; } }
  94. /// <summary>
  95. /// 出版
  96. /// </summary>
  97. public string Publisher { set { _publisher = value; } get { return _publisher; } }
  98. /// <summary>
  99. /// 出版UTF8
  100. /// </summary>
  101. public string PublisherUTF8 { set { _publisherUTF8 = value; } get { return _publisherUTF8; } }
  102. /// <summary>
  103. /// 出版地址
  104. /// </summary>
  105. public string PublisherUrl { set { _publisherUrl = value; } get { return _publisherUrl; } }
  106. /// <summary>
  107. /// 出版地址
  108. /// </summary>
  109. public string PublisherUrlUTF8 { set { _publisherUrlUTF8 = value; } get { return _publisherUrlUTF8; } }
  110. /// <summary>
  111. /// NODES
  112. /// </summary>
  113. public IList<string> Notes { set { _notes = value; } get { return _notes; } }
  114. /// <summary>
  115. /// 包含文件的总长度
  116. /// </summary>
  117. public long TotalLength
  118. {
  119. get
  120. {
  121. return _totalLength;
  122. }
  123. }
  124. #endregion
  125. public Torrent(string fileName)
  126. {
  127. System.IO.FileStream torrentFile = new System.IO.FileStream(fileName, System.IO.FileMode.Open);
  128. byte[] buffer = new byte[torrentFile.Length];
  129. torrentFile.Read(buffer, 0, buffer.Length);
  130. torrentFile.Close();
  131. if ((char)buffer[0] != 'd')
  132. {
  133. if (OpenError.Length == 0) OpenError = "错误的Torrent文件,开头第1字节不是100";
  134. return;
  135. }
  136. GetTorrentData(buffer);
  137. }
  138. #region 开始读数据
  139. /// <summary>
  140. /// 开始读取
  141. /// </summary>
  142. /// <param name="buffer"></param>
  143. private void GetTorrentData(byte[] buffer)
  144. {
  145. int startIndex = 1;
  146. while (true)
  147. {
  148. object Keys = GetKeyText(buffer, ref startIndex);
  149. if (Keys == null)
  150. {
  151. if (startIndex >= buffer.Length) OpenFile = true;
  152. break;
  153. }
  154. if (GetValueText(buffer, ref startIndex, Keys.ToString().ToUpper()) == false) break;
  155. }
  156. }
  157. #endregion
  158. /// <summary>
  159. /// 读取结构
  160. /// </summary>
  161. /// <param name="buffer"></param>
  162. /// <param name="starIndex"></param>
  163. /// <param name="key"></param>
  164. /// <returns></returns>
  165. private bool GetValueText(byte[] buffer, ref int starIndex, string key)
  166. {
  167. switch (key)
  168. {
  169. case "ANNOUNCE":
  170. Announce = GetKeyText(buffer, ref starIndex).ToString();
  171. break;
  172. case "ANNOUNCE-LIST":
  173. int listCount = 0;
  174. ArrayList _tempList = GetKeyData(buffer, ref starIndex, ref listCount);
  175. for (int i = 0; i != _tempList.Count; i++)
  176. {
  177. AnnounceList.Add(_tempList[i].ToString());
  178. }
  179. break;
  180. case "CREATION DATE":
  181. object date = GetKeyNumb(buffer, ref starIndex).ToString();
  182. if (date == null)
  183. {
  184. if (OpenError.Length == 0) OpenError = "CREATION DATE 返回不是数字类型";
  185. return false;
  186. }
  187. CreateTime = CreateTime.AddTicks(long.Parse(date.ToString()));
  188. break;
  189. case "CODEPAGE":
  190. object codePageNumb = GetKeyNumb(buffer, ref starIndex);
  191. if (codePageNumb == null)
  192. {
  193. if (OpenError.Length == 0) OpenError = "CODEPAGE 返回不是数字类型";
  194. return false;
  195. }
  196. CodePage = long.Parse(codePageNumb.ToString());
  197. break;
  198. case "ENCODING":
  199. Encoding = GetKeyText(buffer, ref starIndex).ToString();
  200. break;
  201. case "CREATED BY":
  202. CreatedBy = GetKeyText(buffer, ref starIndex).ToString();
  203. break;
  204. case "COMMENT":
  205. Comment = GetKeyText(buffer, ref starIndex).ToString();
  206. break;
  207. case "COMMENT.UTF-8":
  208. CommentUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  209. break;
  210. case "INFO":
  211. int fileListCount = 0;
  212. GetFileInfo(buffer, ref starIndex, ref fileListCount);
  213. break;
  214. case "NAME":
  215. Name = GetKeyText(buffer, ref starIndex).ToString();
  216. break;
  217. case "NAME.UTF-8":
  218. NameUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  219. break;
  220. case "PIECE LENGTH":
  221. object pieceLengthNumb = GetKeyNumb(buffer, ref starIndex);
  222. if (pieceLengthNumb == null)
  223. {
  224. if (OpenError.Length == 0) OpenError = "PIECE LENGTH 返回不是数字类型";
  225. return false;
  226. }
  227. PieceLength = long.Parse(pieceLengthNumb.ToString());
  228. break;
  229. case "PIECES":
  230. Pieces = GetKeyByte(buffer, ref starIndex);
  231. break;
  232. case "PUBLISHER":
  233. Publisher = GetKeyText(buffer, ref starIndex).ToString();
  234. break;
  235. case "PUBLISHER.UTF-8":
  236. PublisherUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  237. break;
  238. case "PUBLISHER-URL":
  239. PublisherUrl = GetKeyText(buffer, ref starIndex).ToString();
  240. break;
  241. case "PUBLISHER-URL.UTF-8":
  242. PublisherUrlUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  243. break;
  244. case "NODES":
  245. int nodesCount = 0;
  246. ArrayList _nodesList = GetKeyData(buffer, ref starIndex, ref nodesCount);
  247. int ipCount = _nodesList.Count / 2;
  248. for (int i = 0; i != ipCount; i++)
  249. {
  250. Notes.Add(_nodesList[i * 2] + ":" + _nodesList[(i * 2) + 1]);
  251. }
  252. break;
  253. default:
  254. return false;
  255. }
  256. return true;
  257. }
  258. #region 获取数据
  259. /// <summary>
  260. /// 获取列表方式 "I1:Xe"="X" 会调用GetKeyText
  261. /// </summary>
  262. /// <param name="buffer"></param>
  263. /// <param name="starIndex"></param>
  264. /// <param name="listCount"></param>
  265. private ArrayList GetKeyData(byte[] buffer, ref int starIndex, ref int listCount)
  266. {
  267. ArrayList _tempList = new ArrayList();
  268. while (true)
  269. {
  270. string textStar = System.Text.Encoding.UTF8.GetString(buffer, starIndex, 1);
  271. switch (textStar)
  272. {
  273. case "l":
  274. starIndex++;
  275. listCount++;
  276. break;
  277. case "e":
  278. listCount--;
  279. starIndex++;
  280. if (listCount == 0) return _tempList;
  281. break;
  282. case "i":
  283. _tempList.Add(GetKeyNumb(buffer, ref starIndex).ToString());
  284. break;
  285. default:
  286. object listText = GetKeyText(buffer, ref starIndex);
  287. if (listText != null)
  288. {
  289. _tempList.Add(listText.ToString());
  290. }
  291. else
  292. {
  293. if (OpenError.Length == 0)
  294. {
  295. OpenError = "错误的Torrent文件,ANNOUNCE-LIST错误";
  296. return _tempList;
  297. }
  298. }
  299. break;
  300. }
  301. }
  302. }
  303. /// <summary>
  304. /// 获取字符串
  305. /// </summary>
  306. /// <param name="buffer"></param>
  307. /// <param name="startIndex"></param>
  308. /// <returns></returns>
  309. private object GetKeyText(byte[] buffer, ref int startIndex)
  310. {
  311. int numb = 0;
  312. int leftNumb = 0;
  313. for (int i = startIndex; i != buffer.Length; i++)
  314. {
  315. if ((char)buffer[i] == ':') break;
  316. if ((char)buffer[i] == 'e')
  317. {
  318. leftNumb++;
  319. continue;
  320. }
  321. numb++;
  322. }
  323. startIndex += leftNumb;
  324. string textNumb = System.Text.Encoding.UTF8.GetString(buffer, startIndex, numb);
  325. try
  326. {
  327. int readNumb = Int32.Parse(textNumb);
  328. startIndex = startIndex + numb + 1;
  329. object keyText = System.Text.Encoding.UTF8.GetString(buffer, startIndex, readNumb);
  330. startIndex += readNumb;
  331. return keyText;
  332. }
  333. catch
  334. {
  335. return null;
  336. }
  337. }
  338. /// <summary>
  339. /// 获取数字
  340. /// </summary>
  341. /// <param name="buffer"></param>
  342. /// <param name="startIndex"></param>
  343. private object GetKeyNumb(byte[] buffer, ref int startIndex)
  344. {
  345. if (System.Text.Encoding.UTF8.GetString(buffer, startIndex, 1) == "i")
  346. {
  347. int numb = 0;
  348. for (int i = startIndex; i != buffer.Length; i++)
  349. {
  350. if ((char)buffer[i] == 'e') break;
  351. numb++;
  352. }
  353. startIndex++;
  354. long retNumb = 0;
  355. try
  356. {
  357. retNumb = long.Parse(System.Text.Encoding.UTF8.GetString(buffer, startIndex, numb - 1));
  358. startIndex += numb;
  359. return retNumb;
  360. }
  361. catch
  362. {
  363. return null;
  364. }
  365. }
  366. else
  367. {
  368. return null;
  369. }
  370. }
  371. /// <summary>
  372. /// 获取BYTE数据
  373. /// </summary>
  374. /// <param name="buffer"></param>
  375. /// <param name="startIndex"></param>
  376. /// <returns></returns>
  377. private byte[] GetKeyByte(byte[] buffer, ref int startIndex)
  378. {
  379. int numb = 0;
  380. for (int i = startIndex; i != buffer.Length; i++)
  381. {
  382. if ((char)buffer[i] == ':') break;
  383. numb++;
  384. }
  385. string textNumb = System.Text.Encoding.UTF8.GetString(buffer, startIndex, numb);
  386. try
  387. {
  388. int readNumb = Int32.Parse(textNumb);
  389. startIndex = startIndex + numb + 1;
  390. System.IO.MemoryStream keyMemory = new System.IO.MemoryStream(buffer, startIndex, readNumb);
  391. byte[] keyBytes = new byte[readNumb];
  392. keyMemory.Read(keyBytes, 0, readNumb);
  393. keyMemory.Close();
  394. startIndex += readNumb;
  395. return keyBytes;
  396. }
  397. catch
  398. {
  399. return null;
  400. }
  401. }
  402. /// <summary>
  403. /// 对付INFO的结构
  404. /// </summary>
  405. /// <param name="buffer"></param>
  406. /// <param name="startIndex"></param>
  407. /// <param name="listCount"></param>
  408. private void GetFileInfo(byte[] buffer, ref int startIndex, ref int listCount)
  409. {
  410. if ((char)buffer[startIndex] != 'd') return;
  411. startIndex++;
  412. if (GetKeyText(buffer, ref startIndex).ToString().ToUpper() == "FILES")
  413. {
  414. FileInfo info = new FileInfo();
  415. while (true)
  416. {
  417. string TextStar = System.Text.Encoding.UTF8.GetString(buffer, startIndex, 1);
  418. switch (TextStar)
  419. {
  420. case "l":
  421. startIndex++;
  422. listCount++;
  423. break;
  424. case "e":
  425. listCount--;
  426. startIndex++;
  427. if (listCount == 1) FileList.Add(info);
  428. if (listCount == 0) return;
  429. break;
  430. case "d":
  431. info = new FileInfo();
  432. listCount++;
  433. startIndex++;
  434. break;
  435. default:
  436. object listText = GetKeyText(buffer, ref startIndex);
  437. if (listText == null) return;
  438. switch (listText.ToString().ToUpper())   //转换为大写
  439. {
  440. case "ED2K":
  441. info.De2K = GetKeyText(buffer, ref startIndex).ToString();
  442. break;
  443. case "FILEHASH":
  444. info.FileHash = GetKeyText(buffer, ref startIndex).ToString();
  445. break;
  446. case "LENGTH":
  447. info.Length = Convert.ToInt64(GetKeyNumb(buffer, ref startIndex));
  448. _totalLength += info.Length;
  449. break;
  450. case "PATH":
  451. int PathCount = 0;
  452. ArrayList PathList = GetKeyData(buffer, ref startIndex, ref PathCount);
  453. string Temp = "";
  454. for (int i = 0; i != PathList.Count; i++)
  455. {
  456. if (i < PathList.Count && i != 0)
  457. Temp += "\\";
  458. Temp += PathList[i].ToString();
  459. }
  460. info.Path = Temp;
  461. break;
  462. case "PATH.UTF-8":
  463. int pathUtf8Count = 0;
  464. ArrayList pathutf8List = GetKeyData(buffer, ref startIndex, ref pathUtf8Count);
  465. string utfTemp = "";
  466. for (int i = 0; i != pathutf8List.Count; i++)
  467. {
  468. utfTemp += pathutf8List[i].ToString();
  469. }
  470. info.PathUTF8 = utfTemp;
  471. break;
  472. }
  473. break;
  474. }
  475. }
  476. }
  477. }
  478. #endregion
  479. /// <summary>
  480. /// 对应结构 INFO 多个文件时
  481. /// </summary>
  482. public class FileInfo
  483. {
  484. private string path = "";
  485. private string pathutf8 = "";
  486. private long length = 0;
  487. private string md5sum = "";
  488. private string de2k = "";
  489. private string filehash = "";
  490. /// <summary>
  491. /// 文件路径
  492. /// </summary>
  493. public string Path { get { return path; } set { path = value; } }
  494. /// <summary>
  495. /// UTF8的名称
  496. /// </summary>
  497. public string PathUTF8 { get { return pathutf8; } set { pathutf8 = value; } }
  498. /// <summary>
  499. /// 文件大小
  500. /// </summary>
  501. public long Length { get { return length; } set { length = value; } }
  502. /// <summary>
  503. /// MD5验效 (可选)
  504. /// </summary>
  505. public string MD5Sum { get { return md5sum; } set { md5sum = value; } }
  506. /// <summary>
  507. /// ED2K 未知
  508. /// </summary>
  509. public string De2K { get { return de2k; } set { de2k = value; } }
  510. /// <summary>
  511. /// FileHash 未知
  512. /// </summary>
  513. public string FileHash { get { return filehash; } set { filehash = value; } }
  514. }
  515. }
  516. }
[csharp] view plaincopyprint?
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Collections;
  6. namespace XunleiHelper
  7. {
  8. public class Torrent
  9. {
  10. #region 私有字段
  11. private string _openError = "";
  12. private bool _openFile = false;
  13. private string _announce = "";
  14. private IList<string> _announceList = new List<string>();
  15. private DateTime _createTime = new DateTime(1970, 1, 1, 0, 0, 0);
  16. private long _codePage = 0;
  17. private string _comment = "";
  18. private string _createdBy = "";
  19. private string _encoding = "";
  20. private string _commentUTF8 = "";
  21. private IList<FileInfo> _fileList = new List<FileInfo>();
  22. private string _name = "";
  23. private string _nameUTF8 = "";
  24. private long _pieceLength = 0;
  25. private byte[] _pieces;
  26. private string _publisher = "";
  27. private string _publisherUTF8 = "";
  28. private string _publisherUrl = "";
  29. private string _publisherUrlUTF8 = "";
  30. private IList<string> _notes = new List<string>();
  31. private long _totalLength;
  32. #endregion
  33. #region 属性
  34. /// <summary>
  35. /// 错误信息
  36. /// </summary>
  37. public string OpenError { set { _openError = value; } get { return _openError; } }
  38. /// <summary>
  39. /// 是否正常打开文件
  40. /// </summary>
  41. public bool OpenFile { set { _openFile = value; } get { return _openFile; } }
  42. /// <summary>
  43. /// 服务器的URL(字符串)
  44. /// </summary>
  45. public string Announce { set { _announce = value; } get { return _announce; } }
  46. /// <summary>
  47. /// 备用tracker服务器列表(列表)
  48. /// </summary>
  49. public IList<string> AnnounceList { set { _announceList = value; } get { return _announceList; } }
  50. /// <summary>
  51. /// 种子创建的时间,Unix标准时间格式,从1970 1月1日 00:00:00到创建时间的秒数(整数)
  52. /// </summary>
  53. public DateTime CreateTime { set { _createTime = value; } get { return _createTime; } }
  54. /// <summary>
  55. /// 未知数字CodePage
  56. /// </summary>
  57. public long CodePage { set { _codePage = value; } get { return _codePage; } }
  58. /// <summary>
  59. /// 种子描述
  60. /// </summary>
  61. public string Comment { set { _comment = value; } get { return _comment; } }
  62. /// <summary>
  63. /// 编码方式
  64. /// </summary>
  65. public string CommentUTF8 { set { _commentUTF8 = value; } get { return _commentUTF8; } }
  66. /// <summary>
  67. /// 创建人
  68. /// </summary>
  69. public string CreatedBy { set { _createdBy = value; } get { return _createdBy; } }
  70. /// <summary>
  71. /// 编码方式
  72. /// </summary>
  73. public string Encoding { set { _encoding = value; } get { return _encoding; } }
  74. /// <summary>
  75. /// 文件信息
  76. /// </summary>
  77. public IList<FileInfo> FileList { set { _fileList = value; } get { return _fileList; } }
  78. /// <summary>
  79. /// 种子名
  80. /// </summary>
  81. public string Name { set { _name = value; } get { return _name; } }
  82. /// <summary>
  83. /// 种子名UTF8
  84. /// </summary>
  85. public string NameUTF8 { set { _nameUTF8 = value; } get { return _nameUTF8; } }
  86. /// <summary>
  87. /// 每个块的大小,单位字节(整数)
  88. /// </summary>
  89. public long PieceLength { set { _pieceLength = value; } get { return _pieceLength; } }
  90. /// <summary>
  91. /// 每个块的20个字节的SHA1 Hash的值(二进制格式)
  92. /// </summary>
  93. private byte[] Pieces { set { _pieces = value; } get { return _pieces; } }
  94. /// <summary>
  95. /// 出版
  96. /// </summary>
  97. public string Publisher { set { _publisher = value; } get { return _publisher; } }
  98. /// <summary>
  99. /// 出版UTF8
  100. /// </summary>
  101. public string PublisherUTF8 { set { _publisherUTF8 = value; } get { return _publisherUTF8; } }
  102. /// <summary>
  103. /// 出版地址
  104. /// </summary>
  105. public string PublisherUrl { set { _publisherUrl = value; } get { return _publisherUrl; } }
  106. /// <summary>
  107. /// 出版地址
  108. /// </summary>
  109. public string PublisherUrlUTF8 { set { _publisherUrlUTF8 = value; } get { return _publisherUrlUTF8; } }
  110. /// <summary>
  111. /// NODES
  112. /// </summary>
  113. public IList<string> Notes { set { _notes = value; } get { return _notes; } }
  114. /// <summary>
  115. /// 包含文件的总长度
  116. /// </summary>
  117. public long TotalLength
  118. {
  119. get
  120. {
  121. return _totalLength;
  122. }
  123. }
  124. #endregion
  125. public Torrent(string fileName)
  126. {
  127. System.IO.FileStream torrentFile = new System.IO.FileStream(fileName, System.IO.FileMode.Open);
  128. byte[] buffer = new byte[torrentFile.Length];
  129. torrentFile.Read(buffer, 0, buffer.Length);
  130. torrentFile.Close();
  131. if ((char)buffer[0] != 'd')
  132. {
  133. if (OpenError.Length == 0) OpenError = "错误的Torrent文件,开头第1字节不是100";
  134. return;
  135. }
  136. GetTorrentData(buffer);
  137. }
  138. #region 开始读数据
  139. /// <summary>
  140. /// 开始读取
  141. /// </summary>
  142. /// <param name="buffer"></param>
  143. private void GetTorrentData(byte[] buffer)
  144. {
  145. int startIndex = 1;
  146. while (true)
  147. {
  148. object Keys = GetKeyText(buffer, ref startIndex);
  149. if (Keys == null)
  150. {
  151. if (startIndex >= buffer.Length) OpenFile = true;
  152. break;
  153. }
  154. if (GetValueText(buffer, ref startIndex, Keys.ToString().ToUpper()) == false) break;
  155. }
  156. }
  157. #endregion
  158. /// <summary>
  159. /// 读取结构
  160. /// </summary>
  161. /// <param name="buffer"></param>
  162. /// <param name="starIndex"></param>
  163. /// <param name="key"></param>
  164. /// <returns></returns>
  165. private bool GetValueText(byte[] buffer, ref int starIndex, string key)
  166. {
  167. switch (key)
  168. {
  169. case "ANNOUNCE":
  170. Announce = GetKeyText(buffer, ref starIndex).ToString();
  171. break;
  172. case "ANNOUNCE-LIST":
  173. int listCount = 0;
  174. ArrayList _tempList = GetKeyData(buffer, ref starIndex, ref listCount);
  175. for (int i = 0; i != _tempList.Count; i++)
  176. {
  177. AnnounceList.Add(_tempList[i].ToString());
  178. }
  179. break;
  180. case "CREATION DATE":
  181. object date = GetKeyNumb(buffer, ref starIndex).ToString();
  182. if (date == null)
  183. {
  184. if (OpenError.Length == 0) OpenError = "CREATION DATE 返回不是数字类型";
  185. return false;
  186. }
  187. CreateTime = CreateTime.AddTicks(long.Parse(date.ToString()));
  188. break;
  189. case "CODEPAGE":
  190. object codePageNumb = GetKeyNumb(buffer, ref starIndex);
  191. if (codePageNumb == null)
  192. {
  193. if (OpenError.Length == 0) OpenError = "CODEPAGE 返回不是数字类型";
  194. return false;
  195. }
  196. CodePage = long.Parse(codePageNumb.ToString());
  197. break;
  198. case "ENCODING":
  199. Encoding = GetKeyText(buffer, ref starIndex).ToString();
  200. break;
  201. case "CREATED BY":
  202. CreatedBy = GetKeyText(buffer, ref starIndex).ToString();
  203. break;
  204. case "COMMENT":
  205. Comment = GetKeyText(buffer, ref starIndex).ToString();
  206. break;
  207. case "COMMENT.UTF-8":
  208. CommentUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  209. break;
  210. case "INFO":
  211. int fileListCount = 0;
  212. GetFileInfo(buffer, ref starIndex, ref fileListCount);
  213. break;
  214. case "NAME":
  215. Name = GetKeyText(buffer, ref starIndex).ToString();
  216. break;
  217. case "NAME.UTF-8":
  218. NameUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  219. break;
  220. case "PIECE LENGTH":
  221. object pieceLengthNumb = GetKeyNumb(buffer, ref starIndex);
  222. if (pieceLengthNumb == null)
  223. {
  224. if (OpenError.Length == 0) OpenError = "PIECE LENGTH 返回不是数字类型";
  225. return false;
  226. }
  227. PieceLength = long.Parse(pieceLengthNumb.ToString());
  228. break;
  229. case "PIECES":
  230. Pieces = GetKeyByte(buffer, ref starIndex);
  231. break;
  232. case "PUBLISHER":
  233. Publisher = GetKeyText(buffer, ref starIndex).ToString();
  234. break;
  235. case "PUBLISHER.UTF-8":
  236. PublisherUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  237. break;
  238. case "PUBLISHER-URL":
  239. PublisherUrl = GetKeyText(buffer, ref starIndex).ToString();
  240. break;
  241. case "PUBLISHER-URL.UTF-8":
  242. PublisherUrlUTF8 = GetKeyText(buffer, ref starIndex).ToString();
  243. break;
  244. case "NODES":
  245. int nodesCount = 0;
  246. ArrayList _nodesList = GetKeyData(buffer, ref starIndex, ref nodesCount);
  247. int ipCount = _nodesList.Count / 2;
  248. for (int i = 0; i != ipCount; i++)
  249. {
  250. Notes.Add(_nodesList[i * 2] + ":" + _nodesList[(i * 2) + 1]);
  251. }
  252. break;
  253. default:
  254. return false;
  255. }
  256. return true;
  257. }
  258. #region 获取数据
  259. /// <summary>
  260. /// 获取列表方式 "I1:Xe"="X" 会调用GetKeyText
  261. /// </summary>
  262. /// <param name="buffer"></param>
  263. /// <param name="starIndex"></param>
  264. /// <param name="listCount"></param>
  265. private ArrayList GetKeyData(byte[] buffer, ref int starIndex, ref int listCount)
  266. {
  267. ArrayList _tempList = new ArrayList();
  268. while (true)
  269. {
  270. string textStar = System.Text.Encoding.UTF8.GetString(buffer, starIndex, 1);
  271. switch (textStar)
  272. {
  273. case "l":
  274. starIndex++;
  275. listCount++;
  276. break;
  277. case "e":
  278. listCount--;
  279. starIndex++;
  280. if (listCount == 0) return _tempList;
  281. break;
  282. case "i":
  283. _tempList.Add(GetKeyNumb(buffer, ref starIndex).ToString());
  284. break;
  285. default:
  286. object listText = GetKeyText(buffer, ref starIndex);
  287. if (listText != null)
  288. {
  289. _tempList.Add(listText.ToString());
  290. }
  291. else
  292. {
  293. if (OpenError.Length == 0)
  294. {
  295. OpenError = "错误的Torrent文件,ANNOUNCE-LIST错误";
  296. return _tempList;
  297. }
  298. }
  299. break;
  300. }
  301. }
  302. }
  303. /// <summary>
  304. /// 获取字符串
  305. /// </summary>
  306. /// <param name="buffer"></param>
  307. /// <param name="startIndex"></param>
  308. /// <returns></returns>
  309. private object GetKeyText(byte[] buffer, ref int startIndex)
  310. {
  311. int numb = 0;
  312. int leftNumb = 0;
  313. for (int i = startIndex; i != buffer.Length; i++)
  314. {
  315. if ((char)buffer[i] == ':') break;
  316. if ((char)buffer[i] == 'e')
  317. {
  318. leftNumb++;
  319. continue;
  320. }
  321. numb++;
  322. }
  323. startIndex += leftNumb;
  324. string textNumb = System.Text.Encoding.UTF8.GetString(buffer, startIndex, numb);
  325. try
  326. {
  327. int readNumb = Int32.Parse(textNumb);
  328. startIndex = startIndex + numb + 1;
  329. object keyText = System.Text.Encoding.UTF8.GetString(buffer, startIndex, readNumb);
  330. startIndex += readNumb;
  331. return keyText;
  332. }
  333. catch
  334. {
  335. return null;
  336. }
  337. }
  338. /// <summary>
  339. /// 获取数字
  340. /// </summary>
  341. /// <param name="buffer"></param>
  342. /// <param name="startIndex"></param>
  343. private object GetKeyNumb(byte[] buffer, ref int startIndex)
  344. {
  345. if (System.Text.Encoding.UTF8.GetString(buffer, startIndex, 1) == "i")
  346. {
  347. int numb = 0;
  348. for (int i = startIndex; i != buffer.Length; i++)
  349. {
  350. if ((char)buffer[i] == 'e') break;
  351. numb++;
  352. }
  353. startIndex++;
  354. long retNumb = 0;
  355. try
  356. {
  357. retNumb = long.Parse(System.Text.Encoding.UTF8.GetString(buffer, startIndex, numb - 1));
  358. startIndex += numb;
  359. return retNumb;
  360. }
  361. catch
  362. {
  363. return null;
  364. }
  365. }
  366. else
  367. {
  368. return null;
  369. }
  370. }
  371. /// <summary>
  372. /// 获取BYTE数据
  373. /// </summary>
  374. /// <param name="buffer"></param>
  375. /// <param name="startIndex"></param>
  376. /// <returns></returns>
  377. private byte[] GetKeyByte(byte[] buffer, ref int startIndex)
  378. {
  379. int numb = 0;
  380. for (int i = startIndex; i != buffer.Length; i++)
  381. {
  382. if ((char)buffer[i] == ':') break;
  383. numb++;
  384. }
  385. string textNumb = System.Text.Encoding.UTF8.GetString(buffer, startIndex, numb);
  386. try
  387. {
  388. int readNumb = Int32.Parse(textNumb);
  389. startIndex = startIndex + numb + 1;
  390. System.IO.MemoryStream keyMemory = new System.IO.MemoryStream(buffer, startIndex, readNumb);
  391. byte[] keyBytes = new byte[readNumb];
  392. keyMemory.Read(keyBytes, 0, readNumb);
  393. keyMemory.Close();
  394. startIndex += readNumb;
  395. return keyBytes;
  396. }
  397. catch
  398. {
  399. return null;
  400. }
  401. }
  402. /// <summary>
  403. /// 对付INFO的结构
  404. /// </summary>
  405. /// <param name="buffer"></param>
  406. /// <param name="startIndex"></param>
  407. /// <param name="listCount"></param>
  408. private void GetFileInfo(byte[] buffer, ref int startIndex, ref int listCount)
  409. {
  410. if ((char)buffer[startIndex] != 'd') return;
  411. startIndex++;
  412. if (GetKeyText(buffer, ref startIndex).ToString().ToUpper() == "FILES")
  413. {
  414. FileInfo info = new FileInfo();
  415. while (true)
  416. {
  417. string TextStar = System.Text.Encoding.UTF8.GetString(buffer, startIndex, 1);
  418. switch (TextStar)
  419. {
  420. case "l":
  421. startIndex++;
  422. listCount++;
  423. break;
  424. case "e":
  425. listCount--;
  426. startIndex++;
  427. if (listCount == 1) FileList.Add(info);
  428. if (listCount == 0) return;
  429. break;
  430. case "d":
  431. info = new FileInfo();
  432. listCount++;
  433. startIndex++;
  434. break;
  435. default:
  436. object listText = GetKeyText(buffer, ref startIndex);
  437. if (listText == null) return;
  438. switch (listText.ToString().ToUpper())   //转换为大写
  439. {
  440. case "ED2K":
  441. info.De2K = GetKeyText(buffer, ref startIndex).ToString();
  442. break;
  443. case "FILEHASH":
  444. info.FileHash = GetKeyText(buffer, ref startIndex).ToString();
  445. break;
  446. case "LENGTH":
  447. info.Length = Convert.ToInt64(GetKeyNumb(buffer, ref startIndex));
  448. _totalLength += info.Length;
  449. break;
  450. case "PATH":
  451. int PathCount = 0;
  452. ArrayList PathList = GetKeyData(buffer, ref startIndex, ref PathCount);
  453. string Temp = "";
  454. for (int i = 0; i != PathList.Count; i++)
  455. {
  456. if (i < PathList.Count && i != 0)
  457. Temp += "\\";
  458. Temp += PathList[i].ToString();
  459. }
  460. info.Path = Temp;
  461. break;
  462. case "PATH.UTF-8":
  463. int pathUtf8Count = 0;
  464. ArrayList pathutf8List = GetKeyData(buffer, ref startIndex, ref pathUtf8Count);
  465. string utfTemp = "";
  466. for (int i = 0; i != pathutf8List.Count; i++)
  467. {
  468. utfTemp += pathutf8List[i].ToString();
  469. }
  470. info.PathUTF8 = utfTemp;
  471. break;
  472. }
  473. break;
  474. }
  475. }
  476. }
  477. }
  478. #endregion
  479. /// <summary>
  480. /// 对应结构 INFO 多个文件时
  481. /// </summary>
  482. public class FileInfo
  483. {
  484. private string path = "";
  485. private string pathutf8 = "";
  486. private long length = 0;
  487. private string md5sum = "";
  488. private string de2k = "";
  489. private string filehash = "";
  490. /// <summary>
  491. /// 文件路径
  492. /// </summary>
  493. public string Path { get { return path; } set { path = value; } }
  494. /// <summary>
  495. /// UTF8的名称
  496. /// </summary>
  497. public string PathUTF8 { get { return pathutf8; } set { pathutf8 = value; } }
  498. /// <summary>
  499. /// 文件大小
  500. /// </summary>
  501. public long Length { get { return length; } set { length = value; } }
  502. /// <summary>
  503. /// MD5验效 (可选)
  504. /// </summary>
  505. public string MD5Sum { get { return md5sum; } set { md5sum = value; } }
  506. /// <summary>
  507. /// ED2K 未知
  508. /// </summary>
  509. public string De2K { get { return de2k; } set { de2k = value; } }
  510. /// <summary>
  511. /// FileHash 未知
  512. /// </summary>
  513. public string FileHash { get { return filehash; } set { filehash = value; } }
  514. }
  515. }
  516. }

C# 解析种子文件(bt文件)相关推荐

  1. python下载bt文件_bittorrent 种子文件结构解析

    原文链接:http://luoguochun.cn/2014/09/17/bt-file-structure/ 原文作者:buf1024 估计 80% 以上接触互联网的人都知道 bt 是什么东西,任何 ...

  2. # 解析bt文件_BT、磁力链这些词语是什么意思?

    "知其然知其所以然".我们经常在下载资料的时候能看到BT.磁力链等词语,这些词语到底是什么意思呢? 下载都会用,但是你了解吗? BT下载 传统的下载模式是每个客户端从服务器拷贝文件 ...

  3. 种子发布和bt文件分发系统

    基于github开源项目Taipei-Torrent btmaster 主要监听61111端口,可以制作种子和发送种子文件,开启tracker,开启原始下载BT btslave 向btmaster报告 ...

  4. BT文件快速解析算法

    要想实现一个BT下载器,第一步就是解析bt文件: d 8:announce 37:http://tracker.ktxp.com:6868/announce13:announce-listll 37: ...

  5. 路由器OpenWrt如何脱机(离线)下载BT文件

    路由器OpenWrt如何脱机(离线)下载BT文件 1.首先到如下网址下载OpenWrt固件(确保为路由器正确型号). http://downloads.openwrt.org/snapshots/tr ...

  6. 迅播Gvod无法播放BT文件的解决办法,附示例代码

    最近在迅播Gvod影视交流群(82858047)里,有好几位站长朋友出现了这样的情况:把下载下来的BT种子放在了自已空间里,可以确定BT文件是正常的,也确实含有迅播可以播放的文件,路径也正常,但是使用 ...

  7. python 读取文件读出来是什么格式-深入学习python解析并读取PDF文件内容的方法...

    这篇文章主要学习了python解析并读取PDF文件内容的方法,包括对学习库的应用,python2.7和python3.6中python解析PDF文件内容库的更新,包括对pdfminer库的详细解释和应 ...

  8. python中读取文件内容-深入学习python解析并读取PDF文件内容的方法

    这篇文章主要学习了python解析并读取PDF文件内容的方法,包括对学习库的应用,python2.7和python3.6中python解析PDF文件内容库的更新,包括对pdfminer库的详细解释和应 ...

  9. redis-rdb-tools来解析分析reids dump文件及内存使用量

    2019独角兽企业重金招聘Python工程师标准>>> redis-rdb-tools来解析分析reids dump文件及内存使用量 一. 前言 解析redis的dump.rdb文件 ...

  10. awx文件解析_Android so(ELF)文件解析

    一.前言 so文件是啥?so文件是elf文件,elf文件后缀名是.so,所以也被chang常称之为so文件,elf文件是linux底下二进制文件,可以理解为windows下的PE文件,在Android ...

最新文章

  1. HTTP 和 Socket 的区别
  2. 如何在ABAP ALV中具体的控制每个格子中的编辑属性
  3. mysql查询语句习题._MySql数据库基本select查询语句练习题,初学者易懂。
  4. Jquery 获取select,radio 和 checkbox的值
  5. 使用ssh连接WSL
  6. SQL Server中的SQL语句优化与效率问题
  7. (二)使用预定义模型 QStringListModel例子
  8. HttpResponse类
  9. GO语言中的几个关键思想
  10. 超棒的30款JS类库和工具
  11. TCP/UDP Socket调试工具(SocketTool) v4
  12. ”炮灰“团队自主开发,未参考任何Ftp搜索引擎代码,留个纪念。
  13. 修改华为 Echolife HG8010h 的超级用户密码
  14. Google算法更新记录-你想了解的全在这
  15. pcie 对rc操作的ops
  16. Flutter组件--重叠布局/相对布局(Stack,Positioned组件)
  17. tar 命令打包压缩tar.gz,不包含当前文件夹路径
  18. 我,程序员,告诉你年薪30万的程序员转行后,都去做什么工作了
  19. aria2搭建(CentOS 7)
  20. 简单停车位管理系统(C语言版)

热门文章

  1. android组件化解耦,android module解耦组件化总体概述
  2. 【学习笔记】汇编语言入门
  3. android+模拟示波器,基于Android的虚拟示波器软件设计
  4. 如何把极坐标化为直角坐标_极坐标方程化为直角坐标方程
  5. 记一次Maya使用入门
  6. 广东最美的历史古村落,再不去就没了
  7. c语言出现错误c1083,DES 算法,出现异常:fatal error C1083: Cannot open include file: 'des_encode.h'...
  8. hdu4699 Editor(栈)
  9. 2D转换及相关案例实现
  10. python转义字符与原字符