一个人的战争 (1) : Bencoding格式解码

Torrent文件解析及bencoding解码实战教程 哈希算法是一种从任意长度的数据中创建较短的固定长度哈希值的算法。这些算法在生成哈希值时具有以下特点:单向性:从哈希值无法推算出原始数据。一致性:相同的输入总是产生相同的哈希值。高效性:对输入数据进行哈希运算的速度很快。抗碰撞性:找到两个不同输入但产生相同哈希值的情况很难。最常用到的哈希算法包括MD5、SHA-1、SHA-256等,而在BitTorrent中,通常使用SHA-1算法来生成文件片段的哈希值。 阅读详情

        自学C++一年有余,一直想自己开发个什么东西,终于在今年7月份决定写个BT的客户端吧,恩,说干就干,于是开始了这次痛苦的旅程,越深入到各个细节当中越觉得自己可能完不成这个东西了,故决定开始写Blog激励自己一下,也希望能把一个编程新手遇到的各种困难都记录下来,供他人借鉴,也便于自己日后的查寻. 我这人比较罗嗦,可能整个文档中间会夹杂一些个人感悟,期望哪位不幸读到的朋友谅解. 有对P2P一类软件感兴趣的朋友可以加我qq: 2070341一起聊聊, 自己写东西实在是很孤独.

说干就干,说写就写,先从种子文件开始.

(1):  Bencoding格式

         这个东西是所有相关资源的来源,所以必须先搞定. 下面简单阐述一下,大概格式,有兴趣的网友可以到http://wiki.theory.org/BitTorrentSpecification 参照标准.

     Bencoding采用的是一种字典格式,其中包括四种数据类型,string, int, list和dictionary.其中list和dict都是容器,能包含这四种类型的任意一种,dict的key当然就是string,注意,学过设计模式的朋友想到什么了? 对Composite!

string      4:abcd
int           i1234e
list          l4:abcdi1234ee    一个装有一个string和一个int的list
dict         d3:aaal4:abcdi1234eee 一个装有一条记录的字典,key为aaa,value是个list

下面是一段解析bencoding程序的源码,因为整个bencoding文件就是一个dict,所以最后生成的是个dict,然后再用具体的类来解析这个dict得到相应的内容,请看:


/***************************************************************************************/


enum  DataType  { STRING_TYPE, INTEGER_TYPE, LIST_TYPE, DICT_TYPE } ;


class  TypeBase
{
private:
        DataType        obj_type;
public:
        TypeBase(
const DataType &data_type) : obj_type(data_type) {}
        
virtual ~TypeBase() {}
public:
        DataType type() 
const { return obj_type; }
        
virtual void clear() = 0;
        
}
;


class  StringType :  public  TypeBase
{
private:
        
//std::string        m_str;
        std::vector<char>    m_str;
public:
        StringType();
        StringType(
const StringType& other);
        StringType(
const std::vector<char>& str);
        StringType(
const std::string &str);
        
~StringType(){}
        StringType
& operator= (const StringType &other);
        StringType
& operator= (const std::vector<char> &str);
public:
        
void assign(const std::vector<char> &str);
        size_t size() 
const { return m_str.size(); }
        std::
string get_str() const { return std::string(m_str.begin(), m_str.end()); }
        
void get_str(std::vector<char> &str) { str = m_str; }
public:
        
virtual void clear() { m_str.clear(); };
        
}
;

class IntegerType : public TypeBase
{
private:
        t_u_int64            m_int;
public:
        IntegerType();
        IntegerType
& operator=(const t_u_int64 n);
        IntegerType(
const IntegerType& other);
        IntegerType(
const t_u_int64 n);
        IntegerType
& operator=(const IntegerType &other);
        
~IntegerType(){}
        
public:
        t_u_int64 get_int()
const { return m_int; }
        
virtual void clear() {}
}
;



class ListType : public TypeBase
{
public:
        typedef std::list
<TypeBase*>::iterator            ThisIterator;
        typedef std::list
<TypeBase*>::const_iterator    C_Iterator;
private:
        std::list
<TypeBase*>    m_list_data;
private:
        ListType(
const ListType& other);
        ListType
& operator= (const ListType & other);
public:
        ListType();
        
~ListType();
public:
        
void insert(TypeBase *ptype); 
        size_t size() 
{ return m_list_data.size(); }
        ThisIterator begin() 
{ return m_list_data.begin(); }
        ThisIterator end()   
{ return m_list_data.end(); }
        C_Iterator const_begin() 
const { return m_list_data.begin(); }
        C_Iterator const_end() 
const { return m_list_data.end(); }
        
virtual void clear();
}
;



class DictType : public TypeBase
{
public:
        typedef std::map
<StringType*, TypeBase*>::iterator                ThisIterator;
        typedef std::map
<StringType*, TypeBase*>::const_iterator        C_Iterator;
private:
        std::map
<StringType*, TypeBase*> m_map_data;
private:
        DictType(
const DictType&);
        DictType
& operator=(const DictType&);
public:
        DictType() : TypeBase(DICT_TYPE) 
{}
        
~DictType() { clear(); }
public:
        TypeBase
* get_value( const std::string& key);
        
bool set_value(StringType* pstr_bt, TypeBase* ptype_bt);
        size_t size() 
{ return m_map_data.size(); }
        C_Iterator const_begin() 
const { return m_map_data.begin(); }
        C_Iterator const_end() 
const { return m_map_data.end(); }
        ThisIterator begin() 
{ return m_map_data.begin(); }
        ThisIterator end() 
{ return m_map_data.end(); }
public:
        
virtual void clear();
        
}
;

/***************************************************************************************/

 

这个是实现:

 


/***************************************************************************************************************/

void  StringType::assign( const  std::vector < char >   & str)
{
        clear();
        m_str 
= str;
}



StringType::StringType(
const  std::vector < char >   & str) : TypeBase(STRING_TYPE)
{
        assign(str);
}


StringType::StringType(
const  std:: string   & str) : TypeBase(STRING_TYPE)
{
        std::vector
<char> vstr(str.begin(), str.end());
        assign(vstr);
}


StringType
&  StringType:: operator =  ( const  std::vector < char >   & str)
{
        assign(str);
        
return *this;
}



StringType::StringType() : TypeBase(STRING_TYPE), m_str(
0 )  {}

StringType::StringType(
const  StringType  & other) : TypeBase(STRING_TYPE) { assign(other.m_str); }

StringType
&  StringType:: operator =  ( const  StringType  & other) 
{
        
if(this != &other)
                assign(other.m_str);
        
return *this;
}



/*****************************************************************************************************/

IntegerType::IntegerType() : TypeBase(INTEGER_TYPE), m_int(
0 )  {}
IntegerType
&  IntegerType:: operator = ( const  t_u_int64 n)  { m_int = n; return *this; }
IntegerType::IntegerType(
const  IntegerType &  other) : TypeBase(INTEGER_TYPE)
{
        m_int 
= other.m_int;
}


IntegerType::IntegerType(t_u_int64 n) : TypeBase(INTEGER_TYPE), m_int(n) 
{}
IntegerType
&  IntegerType:: operator = ( const  IntegerType  & other)
{
        
if(this != &other)
                m_int 
= other.m_int;
        
return *this;
}





/*****************************************************************************************************/



ListType::ListType() : TypeBase(LIST_TYPE) 
{}

ListType::
~ ListType()  { clear(); }
void  ListType::clear()
{
        ThisIterator beg 
= m_list_data.begin();
        ThisIterator end 
= m_list_data.end();

        
for(ThisIterator it = beg; it != end; ++it)
                delete (
*it);
        
        m_list_data.clear();
}


void  ListType::insert(TypeBase  * ptype)
{
        m_list_data.push_back(ptype);
}




/*****************************************************************************************************/



TypeBase
*  DictType::get_value( const  std:: string   & key)
{
        C_Iterator beg 
= m_map_data.begin();
        C_Iterator end 
= m_map_data.end();
        
        
for(C_Iterator it = beg; it != end; ++it){
                
if((it->first->get_str()) == key){
                        
return (it->second);
                }

        }

        
return NULL;
}



bool  DictType::set_value(StringType *  pstr_bt, TypeBase *  ptype_bt)
{
        m_map_data[pstr_bt] 
= ptype_bt;
        
return true;
}


void  DictType::clear()
{
        ThisIterator    beg 
= m_map_data.begin();
        ThisIterator    end 
= m_map_data.end();
        
for(ThisIterator it = beg; it != end; ++it){
                delete (it
->first);
                delete (it
->second);
        }

}

 


四种类型都派生自一个TypeBase基类, 故ListType和DictType只需装入一个TypeBase*就OK了,Runtime识别的时候用基类的type()const函数返回的DataType 来识别,我这里并没有给基类提供一个更宽大的接口,没必要.

下面是解码类 BExtractor

 


class  BExtractor  :  private  NonCopyable
{
private:
        
private:
        std::vector
<t_byte>        bfile;
public:
        size_t analyzer(size_t beg_pos, TypeBase 
*&pbase);//供给read_list和read_dict递归提取类型
        size_t read_string(size_t beg_pos, StringType &str_bt);
        
//从指定位置开始位置(基于0)
        
//将内容加入到一个ListType中,内部调用analyzer函数, 会导致递归调用
        
//任何错误都将导致返回 0,直接解析失败
        
//如无错误,则返回读取的内容长度,
        size_t read_int(size_t beg_pos, IntegerType &int_bt);
        
        size_t read_list(size_t beg_pos, ListType 
&list_bt);    
        size_t read_dict(size_t beg_pos, DictType 
&dict_bt);
        
//根据执行起始位置(此起始位置
        size_t locate_key(size_t beg_pos, const std::string &key);
public:
         
//接受一段元数据作分析 当然是bencoding file, 如果未搜索到第一个d,则返回false;
        bool set_content(const std::vector<t_byte> &meta); 
        size_t get_content(size_t b, size_t e, std::vector
<t_byte> &content); //根据执行位置提取一段元数据
        void clear() { bfile.clear(); }
public:
        BExtractor()
{};
        
~BExtractor(){};
}
;

 


#define  ASSERT_POS(pos) { /*assert(pos < bfile.size())*/ if(pos >= bfile.size()) return 0;}
#define  ERR_CHECK(num) { /*assert(num != 0);*/if(num == 0) return 0; }

bool  BExtractor::set_content( const  std::vector < t_byte >   & meta) 
{
        std::vector
<t_byte>::const_iterator it;
        it 
= std::find(meta.begin(), meta.end(), 'd');
        
if(it == meta.end()) return false;

        bfile.clear();
        bfile.resize(meta.size());
        std::copy(it, meta.end(), bfile.begin());
        
return true;
}


size_t BExtractor::get_content(size_t b, size_t len, std::vector
< t_byte >   & content)
{
        ASSERT_POS(b);
        ASSERT_POS(b 
+ len);
        content.resize(len);
        std::vector
<t_byte>::const_iterator beg = bfile.begin() + b;
        std::vector
<t_byte>::const_iterator end = beg + len;
        std::copy(beg, end, content.begin());
        
return len;
}



size_t BExtractor::analyzer(size_t beg_pos, TypeBase 
*& pbase)
{
        IntegerType        
*pint = NULL;
        StringType        
*pstr = NULL;
        ListType        
*plist = NULL;
        DictType        
*pdict = NULL;
        
        ASSERT_POS(beg_pos);
        size_t idx 
= beg_pos;
        
char ch = bfile[idx];
        
        
switch(ch){
        
case 'i':
                pint 
= new IntegerType();
                pbase 
= pint;
                
return read_int(idx, *pint);
        
case 'l':
                plist 
= new ListType();
                pbase 
= plist;
                
return read_list(idx, *plist);
        
case 'd':
                pdict 
= new DictType();
                pbase 
= pdict;
                
return read_dict(idx, *pdict);
        
default:
                pstr 
= new StringType();
                pbase 
= pstr;
                
return read_string(idx, *pstr);
        }

}



size_t BExtractor::read_list(size_t beg_pos, ListType 
& list_bt)
{
        TypeBase 
*pbase = NULL;
        
        size_t idx 
= beg_pos + 1;  //跳过'l';
        ASSERT_POS(idx);
        
        
while(bfile[idx] != 'e'){
                size_t i 
= 0;
                i 
= analyzer(idx, pbase);
                ERR_CHECK(i);
                idx 
+= i;
                ASSERT_POS(idx);
                list_bt.insert(pbase);
        }

        
return (idx + 1 - beg_pos);
}






size_t BExtractor::read_dict(size_t beg_pos, DictType 
& dict_bt)
{

        size_t idx 
= beg_pos + 1;        //跳过'd';
        ASSERT_POS(idx);

        TypeBase        
*pbase = NULL;
        StringType        
*pstr = NULL;

        
while(bfile[idx] != 'e'){
                pstr 
= new StringType();
                size_t i 
= 0;
                i 
= read_string(idx, *pstr);
                ERR_CHECK(i);
                idx 
+= i;
                ASSERT_POS(idx);
                i 
= analyzer(idx, pbase);
                ERR_CHECK(i);
                idx 
+= i;
                ASSERT_POS(idx);
                dict_bt.set_value(pstr, pbase);
        }


        
return (idx + 1 - beg_pos);
}



size_t BExtractor::read_string(size_t beg_pos, StringType 
& str_bt)
{
        str_bt.clear();

        std::
string                num;            //得到前面的数值 4:abcd的4
        size_t idx            =    beg_pos;
        
        ASSERT_POS(idx);

        
while(bfile[idx] != ':'){
                num 
+= bfile[idx];
                
++idx;
                ASSERT_POS(idx);
        }

        
        
++idx;                                    //跳过':';

        size_t len 
= atoi(num.c_str());
        
        ASSERT_POS((idx 
+ len));
        
        std::vector
<char>            str(len);

        
for(size_t i = 0; i < len; ++i)
                str[i] 
= bfile[idx + i];
        
        
if(str.size() != len) return 0;
        str_bt 
= str;
        
return (idx + len - beg_pos);
}



size_t BExtractor::read_int(size_t beg_pos, IntegerType 
& int_bt)
{
        size_t idx        
=        beg_pos + 1;    //跳过'i'
        
        ASSERT_POS(idx);

        
if(bfile[idx] == 'e') return 0;        //如果中间无数值数据
        
        std::
string                num;
        
while(bfile[idx] != 'e'){
                
char ch = bfile[idx];
                
if(!std::isdigit(ch) && ch != '-') return 0;
                num 
+= ch;
                
++idx;
                ASSERT_POS(idx);
        }

        
        int_bt 
= atoi(num.c_str());
        
return (idx - beg_pos + 1);
}


        


size_t BExtractor::locate_key(size_t beg_pos, 
const  std:: string   & key)
{
        assert(bfile[beg_pos] 
== 'd');

        size_t idx 
= beg_pos + 1;        //跳过'd';
        ASSERT_POS(idx);
        
        TypeBase        
*pbase = NULL;
        StringType        key_bt;

        
while(bfile[idx] != 'e'){
                size_t i 
= 0;
                i 
= read_string(idx, key_bt);
                ERR_CHECK(i);
                idx 
+= i;
                ASSERT_POS(idx);
                
if(key_bt.get_str() == key)
                        
return idx;

                i 
= analyzer(idx, pbase);

                
if(i == 0 || ((idx + i) >= bfile.size())){
                        delete pbase;
                        
return 0;
                }

                
                idx 
+= i;
        }

        
        delete pbase;
        
return 0;
}



#undef     ASSERT_POS
#undef     ERR_CHECK

 


        这个类负责抽取Bencoding文件为一个巨型的DictType,当然,也可以根据需要再合适的位置进行相应的操作,例如后期的tracker request时候解码tcp tracker返回的信息,这是后话,暂且不提.大概知道是干什么的就成了.下面是对生成的这个DICT类型的信息提取,使用函数


bool  seed_decoder( const  std:: string   & fname, SeedInfo  & seed_info);

 

SeedInfo结构为:

  


struct  FileInfo
{
        t_u_int64                        length;
        std::
string                        md5sum;
        std::list
<std::string>            path;
public:
        FileInfo();
        
~FileInfo() {}
        FileInfo(
const FileInfo& other);
        FileInfo
& operator=(const FileInfo &other);
public:
        
void clear();
        
}
;

struct  SeedInfo
{
        
bool                            is_multi_files;
        std::vector
<t_u_int8>            info_hash;
        
//std::string                        announce;                //tracker服务器的URL(字符串)
        std::list<std::string>            anounce_list;            //备用tracker服务器列表(列表)
        t_u_int64                        creation_date;     
           //种子创建的时间,Unix标准时间格式,从1970 1月1日 00:00:00到创建时间的秒数(整数)
        std::string                        comment;                //备注(字符串)
        std::string                        created_by;                //创建人或创建程序的信息(字符串)
        std::string                        name;                    //多文件时使用,name:最上层的目录名字(字符串)
        t_u_int64                        piece_lengh;            //每个块的大小,单位字节(整数)
        std::vector<char>                pieces;                    //每个块的20个字节的SHA1 Hash的值(二进制格式)
        std::string                        publisher;
        std::
string                        publisher_url;
        std::list
<FileInfo>                files;                    //多文件时使用;
        size_t                            pieces_num;
//utf8扩展
        bool                            is_utf8;
        std::
string                        publisher_url_utf8;
        std::
string                        publisher_utf8;
        std::
string                        name_utf8;
        std::
string                        comment_utf8;
        
private:
        
void copy(const SeedInfo &other);
public:
        SeedInfo();
        SeedInfo(
const SeedInfo& other);
        SeedInfo
& operator= (const SeedInfo &other);
        
~SeedInfo() {}
        
void clear();
}
;

 


        这个函数的内部实现相当混乱,我不作过分的叙述了,日后要改的,这里有必要提一下的是 : std::vector<t_u_int8>   info_hash;  //这个数据成员,

        它是由整个Bencoding格式文件的字典中的"Info" 这个key所对应的dict类型的160位sha1 hash值, 这个有必要说一下,不太清楚的请参阅相关资料,这东西最好从bit的角度理解,故此,info_hash这个数据成员的.size()为20,   typedef unsigned char  t_u_int8;

        这个几个类都被我放到了头文件bencoding_type.h头文件中了.由于本人软件的设计能力有限,所以整个架构比较乱,后面写了一个包括网络,异步I/O,完成端口,code page转换等繁杂的辅助类,相互的耦合度的比较大, 这个相对来说还是最独立的,所以有些源码就不贴了,有需要的朋友请加我QQ.

        Bencoding解码先说到这,明天有空将贴tracker查寻的源码,我尽量保证每天写一篇笔记以记录自己的工作进度!

  

bencoding:Bencoding 是一种以简洁的格式指定和组织数据的方法 编码 Bencoding 是一种以简洁的格式指定和组织数据的方法 这是 Java 中的一个实现。 更多关于 Bencoding 的信息可以在这里找到( ) 立即下载

相关推荐

Java解析bt torrent种子文件的工具类代码分享

Java解析bt torrent种子文件的工具类代码分享,只能用炫酷来形容,感兴趣就下载看看吧

bencoding编码解析器

BT客户端开始一个下载首先要处理的就是torrent文件.而torrent文件使用bencoding编码.所以实现bencoding编码的解析器,就是第一步工作.Bencoding is done as follows:Strings are length-prefixed base ten followed by a colon and the string. For example /4:s

Lightest的专栏 1万+

torrentParser bencoding 解码 种子分析

bencoding 解码 torrent 文件解码 QT 4.7 编译 MFC 用户不能使用

BT种子文件格式

BT种子文件格式BT种子文件使用了一种叫bencoding的编码方法来保存数据。bencoding现有四种类型的数据:srings(字符串),integers(整数),lists(列表),dictionaries(字典)编码规则如下:strings(字符串)编码为::例如: 4:test 表示为字符串"test" 4:例子 表示为字符串“例子”字符串长度单位为字节没开始或结束标记integ

DarkRuler的专栏 3340

自己写的bencoding解析器

学习torrent文件格式时写的,可以判断torrent文件是否合法,把becoding解码,显示,后面还可以细化哈哈

BEncoding Editer

BEncoding编码文件查看器,可以查看BT种子文件内容

Bencode的编码与解码

开源地址: https://github.com/CreateChen/Bencode Nuget: Install-Package Bencode 1. Bencode规则         BEncoding是BitTorrent用在传输数据结构的编码方式,我们最熟悉的“种子”文件,它里面的元数据就是 BEncoding 过的字典表。虽然比用纯二进制编码效率低,但由于结构简单而且不...

weixin_34153893的博客 2392

PLS-SEM(偏最小二乘路径建模)模型拟合优度指标

PLS-SEM(偏最小二乘路径建模)是一种基于方差的分析方法,侧重于预测导向,通过迭代优化路径系数和外部权重来最大化潜变量的解释方差(R²)。其评估指标分为外部测量模型和结构模型两部分:外部测量模型关注潜变量与显变量的关系,通过标准化载荷(>0.7)、信度指标(Cronbach’s α、复合信度CR>0.7)、聚合效度(AVE>0.5)和区分效度(Fornell-Larcker标准、HTMT<0.85)来评估模型的可靠性和有效性。结构模型则检验潜变量间的因果关系,通过路径系数(β值)

wewil_lwin的博客 3235

BitTorrent协议规范

鉴定 BitTorrent是由布莱姆·科恩设计的一个端对端(peer to peer)文件共享协议,此协议使多个peers通过不可信任的网络的文件传输变得更容易。 目的 此规范的目的是详细介绍 BitTorrent 协议规范 v1.0 。Bram 的协议规范网站 http://www.bittorrent.com/protocol.html 简要地叙述了此协议,在部分范围缺少详细的行

dps game 1796

Halcon dyn_threshold详解

dyn_threshold 原型 dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : ) 功能 利用局部阈值分割图像 参数列表 OrigImage (input_object):原始图像 ThresholdImage (input_object):处理后图像(一般采用滤波处理) RegionDynThresh (output_object):分割后区域 Offset (input_control):灰

ZiLiangQin的博客 1万+

联想ThinkPad声卡驱动安装避坑指南:从E470到X1 Carbon的通用解法

本文详细介绍了ThinkPad声卡驱动安装的全流程,从硬件识别到驱动获取、安装技巧及深度排错。涵盖E470到X1 Carbon等不同机型的通用解法,帮助用户解决音频驱动问题,提升使用体验。重点讲解了声音驱动的精准识别和安装策略,确保系统稳定运行。

weixin_29207439的博客 711

Torrent文件的格式分析与解析器实现

Torrent文件以Bencoding编码进行存储,Bencoding有4种数据类型:字符串string,整数integer,列表list和字典dictionary.

YASinger的博客 4505

基于Requests的百度图片搜索爬取技术详解

本文介绍了一种高效获取百度图片搜索数据的混合请求爬虫技术。该技术结合HTML解析与JSON API调用,通过分析百度图片搜索的网络通信模式,实现了首页HTML解析获取初始参数、后续页面直接调用JSON接口的双重机制。系统采用模块化设计,包含Cookies解析、智能请求分发、数据提取、图片下载等核心模块,支持自定义关键词和爬取页数配置。关键技术包括动态参数管理、正则表达式提取、JSON数据处理等,相比传统爬虫方法具有效率高、资源消耗低的优势,为计算机视觉研究提供了可靠的大规模图片数据采集方案。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 422

B编码(Bencoding)

BT Tracker 通信1.torrent种子文件结构1.1 其中info字段又包含以下的结构:对于“单一文件”,其info字段还包含以下信息:对于“多文件”,其info字段则还包含以下信息:2. B(Bencoding)编码 1.torrent种子文件结构 种子文件里的内容其实就是文本,是经过B编码之后的文本。它主要包含以下字段: info,必须。一个描述torrent文件的字典,有两种可能形式,一种是没有目录结构的“单一文件”,一种是有目录结构的“多文件”; announce,必须。tracker服

1814

【实战】Python 携程酒店价格实时抓取爬虫项目全解析

摘要:本文介绍了一个基于Python的携程酒店价格实时抓取系统开发方案。系统采用Requests、BeautifulSoup和Selenium等技术栈,实现了多城市、多日期的酒店数据采集,包括价格、评分、位置等关键信息。通过请求头伪装、IP代理、随机等待等反爬策略,有效应对携程的反爬机制。系统支持数据清洗、去重和CSV/Excel导出,并提供了多线程优化、代理池集成等进阶方案。本文详细阐述了技术原理、代码实现和优化策略,同时强调了数据采集的合法合规性,为旅游行业数据分析提供了可靠的数据获取方案。

2503_91057718的博客 2607

【100%通过率】华为OD机试真题 C++ 实现【打印机队列】【2022.11 Q4 新题】

有5台打印机打印文件,每台打印机有自己的待打印队列。因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中数字越大优先级越高。打印机会从自己的待打印队列中选择优先级最高的文件来打印。如果存在两个优先级一样的文件,则选择最早进入队列的那个文件。现在请你来模拟这5台打印机的打印过程。

MISAYAONE的博客 9947

torrent文件解析器

第二步工作是解析torrent文件,有了bencoding编码解析器 解析torrent文件当然是易如反掌的任务了.实现的封装类CTorrentParser,完成的主要任务有:1.判断torrent文件是否有效2.得到如下的重要信息:        tracker服务器列表        文件列表        分块尺寸        分块个数        分块sha1的数组3.其他的一些次要信

Lightest的专栏 2万+

【Go语言实战】(26) 分布式搜索引擎

基于go语言的分布式搜索引擎

面向生活编程 2380

Python3 解析 torrent 文件

用 python 解析 torrent 文件

想找个地方记录一下自己的想法,于是就有了这些博客 2681

VHDL六层电梯控制器及仿真

六层电梯电梯 设计要求:设计一个六层电梯控制系统要求有超载、关门中断、提前关门清除报警信电梯外人的上升请求信号,电梯外人的下降请求信号, 电梯外人上升请求信号显示电梯外人下降请求信号显示到达楼层信号 设计思路:输入有clk时钟信号(频率为2Hz) full,deng,quick,clr超载、关门中断、提前关门清除报警c_u1,c_u2,c_u3,c_u4,c_u5电梯外人的上升请求c_d2,c_d3,c_d4,c_d5,c_d6 电梯外人的下降请求 d1,d2,d3,d4,d5,d6电梯内人的...

QQ_778132974的博客 1709

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

BT种子结构及bencoding编码解析

一、数据类型 bencode有4种数据类型:string, integer, list 和 dictionary。 strings(字符串) 编码为:<字符串长度>:<字符串> 例如: 4:test 表示为字符串"test" 4:例子 表示为字符串“例子” 字符串长度单位为字节 没开始或结束标记 integers(整数) 编码为:i<整数>e 开始标记...

yetugeng的专栏 5534

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

libtorrent源码分析(三)BT下载相关知识总结

  bt协议有早起的tracker版本(俗称bt1.0)和现在常用的基于DHT的版本(俗称bt2.0),下文为整理的协议相关资料。 tracker版本   bittorrent是一个文件分发协议,它使用url来定位文件而且跟web服务无缝集成。当有多个人同时下载同一个文件时,下载者之间可以互相上传自己已有的那部分文件,让一个文件支持很多人同时下载却只增加小量的带宽负担变成可能,这就是bt协议相比h...

ty的博客 8137

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

下一篇: Exceptional C++ 读书笔记
SolidusSnake
博客等级 码龄20年 1粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值