C# 解析 Torrent 檔案
沒事寫寫BLOG~~~~~
對於這個類在解析Torrent 檔案時候可能有錯誤,請大家指正。先把檔案解析的類貼出來,連線有空再發把。
使用
TorrentFile File = new TorrentFile(openFileDialog1.FileName);
File.TorrentFileInfoClass[] 檔案資訊
File.TorrentAnnounceList 伺服器列表
全部程式碼
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace Zgke.OtherFile
{
/// <summary>
/// Torrent檔案
/// Zgke@Sina.com
/// 2008-08-28
/// </summary>
public class TorrentFile
{
#region 私有欄位
private string _OpenError = "";
private bool _OpenFile = false;
private string _TorrentAnnounce = "";
private IList<string> _TorrentAnnounceList = new List<string>();
private DateTime _TorrentCreateTime = new DateTime(1970,1,1,0,0,0);
private long _TorrentCodePage = 0;
private string _TorrentComment = "";
private string _TorrentCreatedBy = "";
private string _TorrentEncoding = "";
private string _TorrentCommentUTF8 = "";
private IList<TorrentFileInfoClass> _TorrentFileInfo = new List<TorrentFileInfoClass>();
private string _TorrentName = "";
private string _TorrentNameUTF8 = "";
private long _TorrentPieceLength = 0;
private byte[] _TorrentPieces;
private string _TorrentPublisher = "";
private string _TorrentPublisherUTF8 = "";
private string _TorrentPublisherUrl = "";
private string _TorrentPublisherUrlUTF8 = "";
private IList<string> _TorrentNotes = new List<string>();
#endregion
#region 屬性
/// <summary>
/// 錯誤資訊
/// </summary>
public string OpenError { set { _OpenError = value; } get { return _OpenError; } }
/// <summary>
/// 是否正常開啟檔案
/// </summary>
public bool OpenFile { set { _OpenFile = value; } get { return _OpenFile; } }
/// <summary>
/// 伺服器的URL(字串)
/// </summary>
public string TorrentAnnounce { set { _TorrentAnnounce = value; } get { return _TorrentAnnounce; } }
/// <summary>
/// 備用tracker伺服器列表(列表)
/// </summary>
public IList<string> TorrentAnnounceList { set { _TorrentAnnounceList = value; } get { return _TorrentAnnounceList; } }
/// <summary>
/// 種子建立的時間,Unix標準時間格式,從1970 1月1日 00:00:00到建立時間的秒數(整數)
/// </summary>
public DateTime TorrentCreateTime { set { _TorrentCreateTime = value; } get { return _TorrentCreateTime; } }
/// <summary>
/// 未知數字CodePage
/// </summary>
public long TorrentCodePage { set { _TorrentCodePage = value; } get { return _TorrentCodePage; } }
/// <summary>
/// 種子描述
/// </summary>
public string TorrentComment { set { _TorrentComment = value; } get { return _TorrentComment; } }
/// <summary>
/// 編碼方式
/// </summary>
public string TorrentCommentUTF8 { set { _TorrentCommentUTF8 = value; } get { return _TorrentCommentUTF8; } }
/// <summary>
/// 建立人
/// </summary>
public string TorrentCreatedBy { set { _TorrentCreatedBy = value; } get { return _TorrentCreatedBy; } }
/// <summary>
/// 編碼方式
/// </summary>
public string TorrentEncoding { set { _TorrentEncoding = value; } get { return _TorrentEncoding; } }
/// <summary>
/// 檔案資訊
/// </summary>
public IList<TorrentFileInfoClass> TorrentFileInfo { set { _TorrentFileInfo = value; } get { return _TorrentFileInfo; } }
/// <summary>
/// 種子名
/// </summary>
public string TorrentName { set { _TorrentName = value; } get { return _TorrentName; } }
/// <summary>
/// 種子名UTF8
/// </summary>
public string TorrentNameUTF8 { set { _TorrentNameUTF8 = value; } get { return _TorrentNameUTF8; } }
/// <summary>
/// 每個塊的大小,單位位元組(整數)
/// </summary>
public long TorrentPieceLength { set { _TorrentPieceLength = value; } get { return _TorrentPieceLength; } }
/// <summary>
/// 每個塊的20個位元組的SHA1 Hash的值(二進位制格式)
/// </summary>
private byte[] TorrentPieces { set { _TorrentPieces = value; } get { return _TorrentPieces; } }
/// <summary>
/// 出版
/// </summary>
public string TorrentPublisher { set { _TorrentPublisher = value; } get { return _TorrentPublisher; } }
/// <summary>
/// 出版UTF8
/// </summary>
public string TorrentPublisherUTF8 { set { _TorrentPublisherUTF8 = value; } get { return _TorrentPublisherUTF8; } }
/// <summary>
/// 出版地址
/// </summary>
public string TorrentPublisherUrl { set { _TorrentPublisherUrl = value; } get { return _TorrentPublisherUrl; } }
/// <summary>
/// 出版地址
/// </summary>
public string TorrentPublisherUrlUTF8 { set { _TorrentPublisherUrlUTF8 = value; } get { return _TorrentPublisherUrlUTF8; } }
/// <summary>
/// NODES
/// </summary>
public IList<string> TorrentNotes { set { _TorrentNotes = value; } get { return _TorrentNotes; } }
#endregion
public TorrentFile(string FileName)
{
System.IO.FileStream TorrentFile = new System.IO.FileStream(FileName, System.IO.FileMode.Open);
byte[] TorrentBytes = new byte[TorrentFile.Length];
TorrentFile.Read(TorrentBytes, 0, TorrentBytes.Length);
TorrentFile.Close();
if ((char)TorrentBytes[0] != 'd')
{
if (OpenError.Length == 0) OpenError = "錯誤的Torrent檔案,開頭第1位元組不是100";
return;
}
GetTorrentData(TorrentBytes);
}
#region 開始讀資料
/// <summary>
/// 開始讀取
/// </summary>
/// <param name="TorrentBytes"></param>
private void GetTorrentData(byte[] TorrentBytes)
{
int StarIndex = 1;
while (true)
{
object Keys = GetKeyText(TorrentBytes, ref StarIndex);
if (Keys == null)
{
if (StarIndex >= TorrentBytes.Length) OpenFile = true;
break;
}
if (GetValueText(TorrentBytes, ref StarIndex, Keys.ToString().ToUpper()) == false) break;
}
}
#endregion
/// <summary>
/// 讀取結構
/// </summary>
/// <param name="TorrentBytes"></param>
/// <param name="StarIndex"></param>
/// <param name="Keys"></param>
/// <returns></returns>
private bool GetValueText(byte[] TorrentBytes,ref int StarIndex, string Keys)
{
switch (Keys)
{
case "ANNOUNCE":
TorrentAnnounce = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "ANNOUNCE-LIST":
int ListCount = 0;
ArrayList _TempList=GetKeyData(TorrentBytes, ref StarIndex, ref ListCount);
for (int i = 0; i != _TempList.Count; i++)
{
TorrentAnnounceList.Add(_TempList[i].ToString());
}
break;
case "CREATION DATE":
object Date = GetKeyNumb(TorrentBytes, ref StarIndex).ToString();
if (Date == null)
{
if (OpenError.Length == 0) OpenError = "CREATION DATE 返回不是數字型別";
return false;
}
TorrentCreateTime = TorrentCreateTime.AddTicks(long.Parse(Date.ToString()));
break;
case "CODEPAGE":
object CodePageNumb = GetKeyNumb(TorrentBytes, ref StarIndex);
if (CodePageNumb == null)
{
if (OpenError.Length == 0) OpenError = "CODEPAGE 返回不是數字型別";
return false;
}
TorrentCodePage = long.Parse(CodePageNumb.ToString());
break;
case "ENCODING":
TorrentEncoding = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "CREATED BY":
TorrentCreatedBy = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "COMMENT":
TorrentComment = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "COMMENT.UTF-8":
TorrentCommentUTF8 = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "INFO":
int FileListCount = 0;
GetFileInfo(TorrentBytes, ref StarIndex, ref FileListCount);
break;
case "NAME":
TorrentName = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "NAME.UTF-8":
TorrentNameUTF8 = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "PIECE LENGTH":
object PieceLengthNumb = GetKeyNumb(TorrentBytes, ref StarIndex);
if (PieceLengthNumb == null)
{
if (OpenError.Length == 0) OpenError = "PIECE LENGTH 返回不是數字型別";
return false;
}
TorrentPieceLength = long.Parse(PieceLengthNumb.ToString());
break;
case "PIECES":
TorrentPieces = GetKeyByte(TorrentBytes, ref StarIndex);
break;
case "PUBLISHER":
TorrentPublisher = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "PUBLISHER.UTF-8":
TorrentPublisherUTF8 = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "PUBLISHER-URL":
TorrentPublisherUrl = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "PUBLISHER-URL.UTF-8":
TorrentPublisherUrlUTF8 = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "NODES":
int NodesCount = 0;
ArrayList _NodesList = GetKeyData(TorrentBytes, ref StarIndex, ref NodesCount);
int IPCount= _NodesList.Count/2;
for (int i = 0; i != IPCount; i++)
{
TorrentNotes.Add(_NodesList[i * 2] + ":" + _NodesList[(i * 2) + 1]);
}
break;
default:
return false;
}
return true;
}
#region 獲取資料
/// <summary>
/// 獲取列表方式 "I1:Xe"="X" 會呼叫GetKeyText
/// </summary>
/// <param name="TorrentBytes"></param>
/// <param name="StarIndex"></param>
/// <param name="ListCount"></param>
private ArrayList GetKeyData(byte[] TorrentBytes, ref int StarIndex, ref int ListCount)
{
ArrayList _TempList = new ArrayList();
while (true)
{
string TextStar = Encoding.UTF8.GetString(TorrentBytes, StarIndex, 1);
switch (TextStar)
{
case "l":
StarIndex++;
ListCount++;
break;
case "e":
ListCount--;
StarIndex++;
if (ListCount == 0) return _TempList;
break;
case "i":
_TempList.Add(GetKeyNumb(TorrentBytes,ref StarIndex).ToString());
break;
default:
object ListText = GetKeyText(TorrentBytes, ref StarIndex);
if (ListText != null)
{
_TempList.Add(ListText.ToString());
}
else
{
if (OpenError.Length == 0)
{
OpenError = "錯誤的Torrent檔案,ANNOUNCE-LIST錯誤";
return _TempList;
}
}
break;
}
}
}
/// <summary>
/// 獲取字串
/// </summary>
/// <param name="TorrentBytes"></param>
/// <param name="StarIndex"></param>
/// <returns></returns>
private object GetKeyText(byte[] TorrentBytes, ref int StarIndex)
{
int Numb = 0;
int LeftNumb = 0;
for (int i = StarIndex; i != TorrentBytes.Length; i++)
{
if ((char)TorrentBytes[i] == ':') break;
if ((char)TorrentBytes[i] == 'e')
{
LeftNumb++;
continue;
}
Numb++;
}
StarIndex += LeftNumb;
string TextNumb = Encoding.UTF8.GetString(TorrentBytes, StarIndex, Numb);
try
{
int ReadNumb = Int32.Parse(TextNumb);
StarIndex = StarIndex + Numb + 1;
object KeyText = Encoding.UTF8.GetString(TorrentBytes, StarIndex, ReadNumb);
StarIndex += ReadNumb;
return KeyText;
}
catch
{
return null;
}
}
/// <summary>
/// 獲取數字
/// </summary>
/// <param name="TorrentBytes"></param>
/// <param name="StarIndex"></param>
private object GetKeyNumb(byte[] TorrentBytes, ref int StarIndex)
{
if (Encoding.UTF8.GetString(TorrentBytes, StarIndex, 1) == "i")
{
int Numb = 0;
for (int i = StarIndex; i != TorrentBytes.Length; i++)
{
if ((char)TorrentBytes[i] == 'e') break;
Numb++;
}
StarIndex++;
long RetNumb = 0;
try
{
RetNumb=long.Parse(Encoding.UTF8.GetString(TorrentBytes, StarIndex, Numb-1));
StarIndex += Numb;
return RetNumb;
}
catch
{
return null;
}
}
else
{
return null;
}
}
/// <summary>
/// 獲取BYTE資料
/// </summary>
/// <param name="TorrentBytes"></param>
/// <param name="StarIndex"></param>
/// <returns></returns>
private byte[] GetKeyByte(byte[] TorrentBytes, ref int StarIndex)
{
int Numb = 0;
for (int i = StarIndex; i != TorrentBytes.Length; i++)
{
if ((char)TorrentBytes[i] == ':') break;
Numb++;
}
string TextNumb = Encoding.UTF8.GetString(TorrentBytes, StarIndex, Numb);
try
{
int ReadNumb = Int32.Parse(TextNumb);
StarIndex = StarIndex + Numb + 1;
System.IO.MemoryStream KeyMemory = new System.IO.MemoryStream(TorrentBytes, StarIndex, ReadNumb);
byte[] KeyBytes = new byte[ReadNumb];
KeyMemory.Read(KeyBytes, 0, ReadNumb);
KeyMemory.Close();
StarIndex += ReadNumb;
return KeyBytes;
}
catch
{
return null;
}
}
/// <summary>
/// 對付INFO的結構
/// </summary>
/// <param name="TorrentBytes"></param>
/// <param name="StarIndex"></param>
/// <param name="ListCount"></param>
private void GetFileInfo(byte[] TorrentBytes,ref int StarIndex,ref int ListCount)
{
if ((char)TorrentBytes[StarIndex] != 'd') return;
StarIndex++;
if(GetKeyText(TorrentBytes, ref StarIndex).ToString().ToUpper()=="FILES")
{
TorrentFileInfoClass Info = new TorrentFileInfoClass();
while (true)
{
string TextStar = Encoding.UTF8.GetString(TorrentBytes, StarIndex, 1);
switch (TextStar)
{
case "l":
StarIndex++;
ListCount++;
break;
case "e":
ListCount--;
StarIndex++;
if (ListCount == 1) TorrentFileInfo.Add(Info);
if (ListCount == 0) return;
break;
case "d":
Info = new TorrentFileInfoClass();
ListCount++;
StarIndex++;
break;
default:
object ListText = GetKeyText(TorrentBytes, ref StarIndex);
if (ListText == null) return;
switch (ListText.ToString().ToUpper()) //轉換為大寫
{
case "ED2K":
Info.De2K = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "FILEHASH":
Info.FileHash = GetKeyText(TorrentBytes, ref StarIndex).ToString();
break;
case "LENGTH":
Info.Length = Convert.ToInt64(GetKeyNumb(TorrentBytes, ref StarIndex));
break;
case "PATH":
int PathCount=0;
ArrayList PathList = GetKeyData(TorrentBytes, ref StarIndex, ref PathCount);
string Temp = "";
for (int i = 0; i != PathList.Count; i++)
{
Temp += PathList[i].ToString();
}
Info.Path=Temp;
break;
case "PATH.UTF-8":
int PathUtf8Count = 0;
ArrayList Pathutf8List = GetKeyData(TorrentBytes, ref StarIndex, ref PathUtf8Count);
string UtfTemp = "";
for (int i = 0; i != Pathutf8List.Count; i++)
{
UtfTemp += Pathutf8List[i].ToString();
}
Info.PathUTF8=UtfTemp;
break;
}
break;
}
}
}
}
#endregion
/// <summary>
/// 對應結構 INFO 多個檔案時
/// </summary>
public class TorrentFileInfoClass
{
private string path = "";
private string pathutf8 = "";
private long length = 0;
private string md5sum = "";
private string de2k = "";
private string filehash = "";
/// <summary>
/// 檔案路徑
/// </summary>
public string Path { get { return path; } set { path = value; } }
/// <summary>
/// UTF8的名稱
/// </summary>
public string PathUTF8 { get { return pathutf8; } set { pathutf8 = value; } }
/// <summary>
/// 檔案大小
/// </summary>
public long Length { get { return length; } set { length = value; } }
/// <summary>
/// MD5驗效 (可選)
/// </summary>
public string MD5Sum { get { return md5sum; } set { md5sum = value; } }
/// <summary>
/// ED2K 未知
/// </summary>
public string De2K { get { return de2k; } set { de2k = value; } }
/// <summary>
/// FileHash 未知
/// </summary>
public string FileHash { get { return filehash; } set { filehash = value; } }
}
}
}
相關文章
- Torrent檔案的解析與轉換
- C#解析XML檔案C#XML
- c#(解析xml檔案基礎方法)C#XML
- Windows10系統開啟torrent檔案的方法Windows
- BT種子的技術原理是什麼?.torrent檔案如何理解?
- torrent cache websiteWeb
- c#檔案操作C#
- C# 檔案操作C#
- C#檔案列表C#
- C#配置檔案C#
- eml檔案解析
- Class檔案解析
- Taipei-Torrent使用AI
- c#壓縮檔案C#
- C# 建立XML檔案C#XML
- C#檔案下載C#
- c# 呼叫.bat檔案C#BAT
- jdom解析xml檔案XML
- java class檔案解析Java
- BVH檔案格式解析
- Nginx配置檔案解析Nginx
- GData解析XML檔案XML
- redis配置檔案解析Redis
- jquery 解析xml檔案jQueryXML
- oracle trace檔案解析Oracle
- ISO檔案解析(轉)
- XML 檔案解析實踐 (DOM 解析)XML
- C#讀取文字檔案和寫文字檔案C#
- C#讀取Xml檔案C#XML
- C# 壓縮PDF檔案C#
- C# 檔案IO常用類C#
- C#分割檔案內容C#
- C# 建立壓縮檔案C#
- C# 對XML檔案控制C#XML
- C# 重新命名檔案C#
- c#讀寫ini檔案C#
- C# 批量複製檔案C#
- c# 上傳FTP檔案C#FTP