各位在工作着的大哥大姐,师兄前辈!你们给小弟看看俺这编码水平能找到工作么?

来源:互联网 发布:国外手机直播软件 编辑:程序博客网 时间:2024/05/17 02:02

下面是我做的一个B编码解码代码,准备用于BT下载软件中种子文件解析!功能正常。目前我认为的缺陷是我封装的数据没法做到完全封闭!考虑这块代码常规下只执行一遍,因而未做改动。

个人信息:年龄:20,学历:大专,关键是没有拿到毕业证。所以忐忑......

头文件:

/****************************************************************************************************************文件名:ResovlerMetafile.h**文件职能:声明bt种子文件解析类,**创建日期:2013-08-06**创建人:tmfish****************************************************************************************************************/#ifndef RESOLVERMETAFILE_H_#define RESOLVERMETAFILE_H_#define DEBUG#include <iostream>#include <cstdio>#include <vector>#include <string>#include <cstring>#include <cstdlib>#include <fstream>#include <cctype>#include "sha1.h"using namespace std;typedefint FILETYPE;//文件类型/*状态标识*/typedefint  STATE;        //状态constintNOFILE      = 2;//文件为空constintOK= 0;//成功标识constint ERROR= -1;//错误标识/*文件类型标识*/constintISSIMPLE=1;//单文件标识constintISMULTIPLE=2;//多文件标识struct Files//多文件中的多个文件{intlength;//单个文件的长度char*path;//单个文件的路径及文件名};/******************************************************************************************************************种子文件信息结构体**用于存储种子文件的主要信息**成员说明flagFileType标识文件是单文件还是多文件,当其值为ISSIMPLE的时候表示单文件,所有的多文件特有属性(m_name,files,)失效当其值为ISMULTIPLE的时候表示多文件,多有单文件特有属性失效(s_name,length)pieceLen指定piece的大小 通常为256KB、亦有128kb或512kb 单位为字节 pieces每个piece对应hash值file_name单文件的文件名fileLength文件的总文件长度dir_name多文件存放所有文件的目录名称multi_files多文件中包含的所有文件的信息tracker_listtracker地址列表,其类型为一个string类型的vector数组第一个元素是主tracker地址info_hash根据info关键字的值计算的哈希值,固定为20字节*****************************************************************************************************************/typedef struct MetafileInfo{/*标识文件属性*/intfileType;/*单文件、多文件共有属性*/long pieceLen;//每个piece的长度char*pieces;//每个piece对应的hash值long long fileLength;//文件总大小vector<const char*>trackerList;//tracker地址列表/*单文件特有属性*/char*fileName;//文件名/*多文件特有属性*/char* dirName;//存放所有文件的文件夹名vector<Files>multiFiles;//多文件中所有文件信息unsigned charinfo_hash[20];//根据info关键字的值计算的哈希值。}* pMetaInfo;/*种子文件解析类*/class ResolverMetafile{public:/*构造及析构函数*/ResolverMetafile(string MetafilePath);~ResolverMetafile();/*********************************************************************功能:获取共享文件信息*返回:函数返回存储种子文件信息的m_metaInfo结构体对象*参数:st_info是一个MetafileInfo类型的常引用,用于接收种子文件信息   存放点地址*附注:该函数是文件解析类对外提供的主要接口*********************************************************************/MetafileInfo GetMetafileInfo(pMetaInfo*const ppst_info);/* * 功能:向tracker列表添加一个tracker服务器地址 * 返回:成功添加tracker返回1,tracker已经存在返回0 *  函数成功执行失败返回-1 * 参数:url指定添加的tracker地址,如果该地址存在与tracker *  列表中,则函数退出 * 附注:当连接某些tarcker地址的时候,服务器会返回一个重定向地址,函数用于 *  添加该类地址,当调用该函数后,调用者应该重新调用GetMetafileInfo获取数据 */STATE AddTracker(const char* url);protected:/* * 功能:更具info关键字的值计算其对应的哈希值,将其填充与m_metaInfo.info_hash内 * 返回:成功返回0,失败返回-1 * 附注:info关键字对应的值为一个字典。 */ STATE CalcInfoHash();/* * 功能:读取m_metafilePath指定的种子文件,将文件内容保存到m_metafile中 * 返回:函数成功执行返回1,m_metafilePath为空返回2,失败返回-1 * 附注:文件读取方式为二进制读取*/STATEReadMetafile();/* * 功能:判断种子文件类型 * 返回:单文件返回ISSIMPLE,多文件返回ISMULTIPLE,m_metafile为空返回2 * 附注:ISSIMPLE值为1,ISMULTIPLE值为2*/FILETYPEFileType();/* *功能:在m_metafile中查找指定关键字 *返回:函数查找到指定的关键字返回1,没有找到返回0,函数执行出错返回-1 *参数:word为需要查找的指定关键字,index为查找到的字符串的起始下标*/STATEFindWord(const char* word, long long& index);/* * 功能:解析种子文件的tracker服务器列表,将其放入m_metaInfo.trackerList * 返回:函数成功执行返回0,失败返回-1 * 附注:m_metaInfo.trackerList第一个值为主tracker服务器*/STATEResTracker();/* * 功能:解析piece快大小,将其放入m_metaInfo.pieceLen * 返回:成功执行返回0,失败返回-1,m_metafile为空返回2*/ STATEResPieceLen();/* * 功能:解析每个块对应的hash值字符串,将其放入m_metaInfo.pieces * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2 */ STATEResPieces(); /* * 功能:解析文件名,对于多文件而言解析目录名, *       若解析单文件,放入m_metaInfo.filename,若解析多文件,放入dirName * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2 */ STATEResFileName();/* * 功能:解析总文件大小,填充m_metaInfo.fileLength * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2 */ STATE ResFileLength();/* * 功能:解析文件大小和路径,仅对多文件有效,填充m_metaInfo.multiFiles结构体 * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2 */ STATEResFilePathLen(); /* * 功能:释放类资源 */ void ReleaseMem();protected:/*种子文件信息*/MetafileInfom_metaInfo; /*存储种子文件路径*/ stringm_metafilePath; /*存储种子文件的内容*/ unsigned char*  m_metafile; /*种子文件大小*/long long int m_metafileLen;#ifdef DEBUGpublic:/*测试函数*/void Test();#endif};#endif 
源文件
/* * resolvermetafile.cpp * 对resolverMetafile类的具体实现 *  Created on: 2013-8-6 *      Author: tmfish */#include "resolverMetafile.h"#ifdef DEBUG//测试函数void ResolverMetafile::Test(){cout << "测试函数" << endl;//合格测试//*successfulcout << "filetype:  "<< m_metaInfo.fileType << endl;cout << "piecelen:"<< m_metaInfo.pieceLen << endl;if (ISSIMPLE == m_metaInfo.fileType){cout << "filename:"<< m_metaInfo.fileName<< endl;}else if (ISMULTIPLE == m_metaInfo.fileType){cout << "dirname:"<< m_metaInfo.dirName<< endl;}cout << "multiple files number: " << m_metaInfo.multiFiles.size() << endl;for (int i=0; i<int(m_metaInfo.multiFiles.size()); i++){cout << "path:   " << m_metaInfo.multiFiles[i].path << endl;cout << "length: " << m_metaInfo.multiFiles[i].length << endl;}cout << "fileLen:"<< m_metaInfo.fileLength<< endl;for(int i=0; i<int(m_metaInfo.trackerList.size()); i++){cout << "trackerList" << i << ": " << m_metaInfo.trackerList[i] << endl;}cout << "test for add " << endl;char url[] = "http://baidu.com";AddTracker(url);for(int i=0; i<int(m_metaInfo.trackerList.size()); i++){cout << "trackerList" << i << ": " << m_metaInfo.trackerList[i] << endl;}}#endif//构造函数ResolverMetafile::ResolverMetafile(string path){memset(&m_metaInfo, 0, sizeof(m_metaInfo));m_metafile= NULL;m_metafilePath = path;m_metafileLen = 0;ReadMetafile();FileType();ResTracker();ResPieceLen();ResPieces();ResFileName();ResFilePathLen();ResFileLength();CalcInfoHash();}//析构函数ResolverMetafile::~ResolverMetafile(){/*某些释放*/ReleaseMem();}/*********************************************************************功能:获取共享文件信息*返回:函数返回存储种子文件信息的m_metaInfo结构体对象*参数:pst_info是一个MetafileInfo类型的指针的指针,用于接收种子文件信息   存放点地址*********************************************************************/MetafileInfo ResolverMetafile::GetMetafileInfo(pMetaInfo*const ppst_info){*ppst_info = &m_metaInfo;return m_metaInfo;}/* * 功能:向tracker列表添加一个tracker服务器地址 * 返回:成功添加tracker返回1,tracker已经存在返回0 *  函数成功执行失败返回-1 * 参数:strTracker指定添加的tracker地址,如果该地址存在与tracker *  列表中,则函数退出 * 附注:当连接某些tarcker地址的时候,服务器会返回一个重定向地址,函数用于 *  添加该类地址 */STATE ResolverMetafile::AddTracker(const char* url){char* bufTmp = new char[strlen(url)+1];memcpy(bufTmp,url,strlen(url)+1);int size = m_metaInfo.trackerList.size();//若地址存在,则无需添加for (int i=0; i<size; i++){if (0 == strcmp(m_metaInfo.trackerList.at(i),url)){return OK;}}//于末尾追加元素m_metaInfo.trackerList.push_back(bufTmp);return OK;}/* * 功能:判断种子文件类型 * 返回:单文件返回ISSIMPLE,多文件返回ISMULTIPLE,m_metafile为空返回2 * 附注:ISSIMPLE值为1,ISMULTIPLE值为2*/FILETYPE ResolverMetafile::FileType(){//cout << m_metafile << endl;long long  index; //种子文件中files代表多文件if (1 == FindWord("5:files",index)){m_metaInfo.fileType = ISMULTIPLE;return ISMULTIPLE;}else{m_metaInfo.fileType = ISSIMPLE;return ISSIMPLE;}return ERROR;}/** 功能:读取m_metafilePath指定的种子文件,将文件内容保存到m_metafile中* 返回:函数成功执行返回0,m_metafilePath为空返回2,失败返回-1* 附注:文件读取方式为二进制读取*/STATE ResolverMetafile::ReadMetafile(){if (m_metafilePath.empty()){cerr << "文件路径为空!" << endl;return ERROR;}/*ifstream fin(m_metafilePath.c_str(), ios_base::in | ios_base::binary);//fin.open("in");if (!fin.is_open()){cerr<< "文件打开失败!" << endl;return ERROR;}//获取种子文件长度fin.seekg(0,ios::end);m_metafileLen = fin.tellg();m_metafile = new char[m_metafileLen+1];//fin.read(m_metafile, m_metafileLen);]fin >> m_metafile;if (NULL == m_metafile){cerr << "文件读取失败" << endl;return ERROR;}m_metafile[m_metafileLen] = '\0';cout << m_metafile[3] << endl;fin.close();*///以二进制、只读方式打开文件FILE* fp = fopen(m_metafilePath.c_str(), "rb");if (NULL == fp){cout << "文件打开失败" << endl;return -1;}//获取种子文件的长度,fseek(fp, 0, SEEK_END);m_metafileLen= ftell(fp);if (-1 == m_metafileLen){cout << "文件长度错误" << endl;return -1;}m_metafile = new unsigned char[m_metafileLen+1];if (NULL == m_metafile){cout << "内存分配失败" << endl;return -1;}//读取种子文件的内容到m_metafilefseek(fp, 0, SEEK_SET);long i;for ( i=0; i<m_metafileLen; i++){m_metafile[i] = fgetc(fp);}m_metafile[i] = '\0';fclose(fp);return OK;}/**功能:在m_metafile中查找指定关键字*返回:函数查找到指定的关键字返回1,没有找到返回0,函数执行出错返回-1*参数:word为需要查找的指定关键字,index为查找到的字符串的起始下标的引用*/STATE ResolverMetafile::FindWord(const char* word, long long& index){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return ERROR;}for (long long  int i=0; i<(m_metafileLen-long(strlen(word))); i++){if (0 == memcmp(&m_metafile[i], word, strlen(word))){index = i;return 1;}}//未找到return 0;}/** 功能:解析种子文件的tracker服务器列表,将其放入m_metaInfo.trackerList* 返回:函数成功执行返回0,失败返回-1* 附注:m_metaInfo.trackerList第一个值为主tracker服务器*/STATE ResolverMetafile::ResTracker(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return ERROR;}long long index = 0;if (0 == FindWord("13:announce-list",index)) //单文件处理{if (1 == FindWord("8:annouce",index)){int len  = 0; //tracker长度index = index + strlen("8:announce"); //跳过"8:announce"while (isdigit(m_metafile[index])){len = len*10 + (m_metafile[index] - '0');index++;}index ++; //跳过':'//填充m_metaInfo.trackerList数据成员char* tmpBuf  = new char[len+1];memcpy(tmpBuf, &m_metafile[index], len);tmpBuf[len] = '\0';if(!m_metaInfo.trackerList.empty()){m_metaInfo.trackerList.clear();}m_metaInfo.trackerList.push_back(tmpBuf);}//end if}else   //如果有“13:announce-list”关键字,则不用处理"8:annoucne"关键字{index+=strlen("13:announce-list"); //跳过"13:announce-list"index++;//跳过'l'index++;//跳过'l'int len = 0;while('e' != m_metafile[index]){while(isdigit(m_metafile[index])){len = len*10 + (m_metafile[index]-'0');index++;}index++;//跳过':'//提取tracker 放入m_metafile.trackerList容器//只处理"http"开头的地址if (0 == memcmp(&m_metafile[index],"http",4)){char* tmpBuf  = new char[len+1];memcpy(tmpBuf, &m_metafile[index], len);tmpBuf[len] = '\0';m_metaInfo.trackerList.push_back(tmpBuf);}//准备读取下一个tracker地址index = index + len;len =0;} //end while 1}  //end if elsereturn OK;}/** 功能:解析piece快大小,将其放入m_metaInfo.pieceLen* 返回:成功执行返回0,失败返回-1,m_metafile为空返回2*/STATE ResolverMetafile::ResPieceLen(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return ERROR;}m_metaInfo.pieceLen = 0;long long index  =0;if (1 == FindWord("12:piece length", index)){index += strlen("12:piece length"); //跳过"12:piece length"index ++;//跳过':'//填充m_metaInfo.pieceLenwhile(isdigit(m_metafile[index])){m_metaInfo.pieceLen = 10*(m_metaInfo.pieceLen) + (m_metafile[index]-'0');index++;}}else{return ERROR;}return OK;}/** 功能:解析每个块对应的hash值字符串,将其放入m_metaInfo.pieces* 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2*/STATE ResolverMetafile::ResPieces(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return ERROR;}long long index = 0;if (1 == FindWord("6:pieces", index)){index += strlen("6:pieces");long len = 0;while (isdigit(m_metafile[index])){len = len*10 + (m_metafile[index]-'0');index++;}//填充m_metaInfo.piecesindex++;//跳过':'m_metaInfo.pieces = new char[len+1];memcpy(m_metaInfo.pieces, &m_metafile[index], len);m_metaInfo.pieces[len] = '\0';}else{return ERROR;}return OK;}/** 功能:解析文件名,对于多文件而言解析目录名,*       若解析单文件,放入m_metaInfo.filename,若解析多文件,放入dirName* 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2*/STATE ResolverMetafile::ResFileName(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return ERROR;}long long  index;int count = 0;if (1 == FindWord("4:name", index)){index = index + 6;//跳过'4:name'while (':' != m_metafile[index] ){count = count*10+(m_metafile[index]-'0');index++;}index++;//跳过':'if (ISSIMPLE == m_metaInfo.fileType){m_metaInfo.fileName  = new char[count+1];memcpy(m_metaInfo.fileName,&m_metafile[index], count);m_metaInfo.fileName[count] ='\0';}else if(ISMULTIPLE == m_metaInfo.fileType){m_metaInfo.dirName  = new char[count+1];memcpy(m_metaInfo.dirName,&m_metafile[index], count);m_metaInfo.dirName[count] ='\0';}}else{return ERROR;}return OK;}/** 功能:解析总文件大小,填充m_metaInfo.fileLength* 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2*/STATE ResolverMetafile::ResFileLength(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return ERROR;}long long index = 0;long long size = 0;if (ISSIMPLE == m_metaInfo.fileType ){cout << "enter simple file process " << endl;if (1 == FindWord("6:length",index)) //单文件{index = index+strlen("6:length"); //跳过"6:length"index ++ ;//跳过'i'while(isdigit(m_metafile[index])){size = size*10 + (m_metafile[index]-'0');index++;}m_metaInfo.fileLength = size;} //end if}else if(ISMULTIPLE == m_metaInfo.fileType){for(int i=0; i<int(m_metaInfo.multiFiles.size()); i++){m_metaInfo.fileLength = m_metaInfo.fileLength +m_metaInfo.multiFiles[i].length;}}else{return ERROR;}return OK;}/** 功能:解析文件大小和路径,仅对多文件有效,填充m_metaInfo.multiFiles结构体*  并将files填充,代表多文件的文件个数* 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2*/STATE ResolverMetafile::ResFilePathLen(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return NOFILE;}//不是多文件该函数无效if (ISMULTIPLE != m_metaInfo.fileType){return ERROR;}int length  = 0;//char* path  = NULL;int pathSize = 0;Files   mfBuf ;memset(&mfBuf, 0, sizeof(mfBuf));for(long i=0; i<(m_metafileLen-8); i++) //-8预留空间,防内存溢出{//获取多文件中各个文件的大小if (0 == memcmp(&m_metafile[i], "6:length", 8)){i+=8;//跳过"6:length"i++;//跳过'i'length = 0;while('e' != m_metafile[i]){length = length*10 + (m_metafile[i]-'0');i++;}mfBuf.length = length;//填充m_metaInfo.multiFiles成员,于末尾追加m_metaInfo.multiFiles.push_back(mfBuf);}//end if//获取多文件中文件路径if (0 == memcmp(&m_metafile[i], "4:path", 4)){i+=6; //跳过"4:path"i++;  //跳过 'l'pathSize = 0;while(':' != m_metafile[i]){pathSize = pathSize*10 + (m_metafile[i] - '0');i++;}i++; //跳过':'//填充m_metaInfo.multiFiles成员,于末尾追加int end = m_metaInfo.multiFiles.size();(m_metaInfo.multiFiles[end-1]).path = new char[pathSize+1];memcpy((m_metaInfo.multiFiles[end-1]).path, &m_metafile[i], pathSize);(m_metaInfo.multiFiles[end-1]).path[pathSize]  = '\0';}//end if} //end forreturn OK;}/* * 功能:更具info关键字的值计算其对应的哈希值,将其填充与m_metaInfo.info_hash内 * 返回:成功返回0,失败返回-1 * 附注:info关键字对应的值为一个字典。 */STATE ResolverMetafile::CalcInfoHash(){if (NULL == m_metafile){cerr << "种子内容为空" << endl;return NOFILE;}//begin 为info关键字值开始下标,end为结束int push_pop = 0;long long index=0,begin=0,end=0;if (1 == FindWord("4:info", index)){begin = index+6;}else{return ERROR;}index +=6; //跳过"4:info"/* * 核心算法: 遍历info关键字后的值,当遇到d,l时push_pop++, *   如果遇到e,则push_pop--当push_pop为0的时候, *   则证明info关键字后的字典结束,遇见i则直接遍历 *   i的内容,遇见数字则直接计算其后字串内容 */for (;index<m_metafileLen;){if ('d' == m_metafile[index]){push_pop++;index++;}else if ('l' == m_metafile[index]){push_pop++;index++;}else if ('i' == m_metafile[index]){index++;//跳过'i'if (index > m_metafileLen){return ERROR;}while ('e' != m_metafile[index]){if (index+1 == m_metafileLen){return ERROR;}else{index ++;}}//end whileindex ++; //跳过'e'}else if(('0'<=m_metafile[index]) && (m_metafile[index] <= '9')){int len =0;while (isdigit(m_metafile[index])){len = len*10 + (m_metafile[index]-'0');index++;}index++;//跳过':'index+=len;}else if ('e' == m_metafile[index]){push_pop --;if (0 == push_pop){end = index; break;}index++;}else{return ERROR;}}//end for//计算hash值SHA1_CTX context;SHA1Init(&context);SHA1Update(&context,&m_metafile[begin], end-begin+1);SHA1Final(m_metaInfo.info_hash,&context);cout << endl;return OK;}/* * 功能:释放类资源 */void ResolverMetafile::ReleaseMem(){if (NULL != m_metafile){delete[] m_metafile;m_metafile = NULL;}if (NULL != m_metaInfo.pieces){delete[] m_metaInfo.pieces;}if (!m_metaInfo.trackerList.empty()){for (int i=0; i< int(m_metaInfo.trackerList.size()); i++){delete[] m_metaInfo.trackerList.at(i);m_metaInfo.trackerList.at(i) = NULL;}}m_metaInfo.trackerList.clear();if (!m_metaInfo.multiFiles.empty()){for (int i=0; i<int(m_metaInfo.multiFiles.size()); i++){if (NULL != (m_metaInfo.multiFiles.at(i).path))delete[] m_metaInfo.multiFiles.at(i).path;m_metaInfo.multiFiles.at(i).path = NULL;}}m_metaInfo.multiFiles.clear();memset(&m_metaInfo, 0, sizeof(m_metaInfo));}


原创粉丝点击