BCode解码练习
在学习BT协议中的一个小练习
参考了 https://github.com/airtrack/bitwave
具体B编码解释 可以自行搜索或者参考 这篇文章
bittorrent 学习(一) 种子文件分析与bitmap位图
代码
#pragma once
#include "pre.h"
#include <string>
#include <vector>
#include <iostream>
#include <list>
#include <map> NAMESPACE(DEF) class BCode
{
public:
enum BCODE_TYPE {
BCODE_BASE_TYPE = ,
BCODE_STRING_TYPE = ,
BCODE_INTENGER_TYPE = ,
BCODE_LIST_TYPE = ,
BCODE_DICT_TYPE =
}; BCode(BCODE_TYPE type);
BCODE_TYPE GetBCodeType()const { return type_; }
virtual ~BCode(); protected:
BCODE_TYPE type_;
long long begin_;
long long end_;
}; class BCodeString :public BCode {
public:
explicit BCodeString(long long& begin, long long& end,
const std::vector<char>& data); bool ReadString(long long& begin,long long& end,int stringLen );
int ReadStringLen(long long& begin, long long& end);
std::string std_string() { return bcodeStr_; }
private:
const std::vector<char>& data_;
std::string bcodeStr_;
}; class BCodeIntenger :public BCode {
public:
explicit BCodeIntenger(long long& begin, long long& end,
const std::vector<char>& data); private:
const std::vector<char>& data_;
long long bcodeInt_;
}; class BCodeList :public BCode {
public:
typedef std::list<std::shared_ptr<BCode>> BCodeLists;
explicit BCodeList(long long& begin, long long& end,
const std::vector<char>& data); private:
BCodeList(const BCodeList&) = delete;
BCodeList& operator=(const BCodeList&) = delete;
BCodeLists bcodeList_;
const std::vector<char>& data_;
}; class BCodeDictionary :public BCode {
public:
typedef std::map<std::string, std::shared_ptr<BCode> > BCodemap;
typedef BCodemap::value_type pair_type; explicit BCodeDictionary(long long& begin, long long& end,
const std::vector<char>& data);
private:
BCodeDictionary(const BCodeDictionary&) = delete;
BCodeDictionary& operator=(const BCodeDictionary&) = delete;
const std::vector<char>& data_;
BCodemap bcodeMap_;
}; std::shared_ptr<BCode> GetBCodeObject(long long& begin,
long long& end,const std::vector<char>& data); NAMESPACEEND(DEF)
BCode.h
#include "BCode.h" NAMESPACE(DEF) BCode::BCode(BCODE_TYPE type)
:type_(type),begin_(),end_(){} BCode::~BCode(){} bool BCodeString::ReadString(
long long& begin,
long long& end,
int stringLen)
{
bool b = false;
long long stringEnd = begin + stringLen;
if (stringEnd > end) {
std::cerr << __FUNCTION__ << ". string range error!" << std::endl;
return b;
}
bcodeStr_.assign(&data_[begin], stringLen);
begin = stringEnd;
#ifdef _DEBUG_PRINT
std::cout << __FUNCTION__ << ". BCodeString = "
<< bcodeStr_ << std::endl; #endif // DEBUG b = true;
return b;
} BCodeString::BCodeString(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeStr_(), BCode(BCODE_STRING_TYPE), data_(data)
{
begin_ = begin;
int stringLen = ReadStringLen(begin, end);
if (stringLen <= || begin >= end || data_[begin] != ':') {
std::cerr << __FUNCTION__ << ". string length error!" << std::endl;
return;
}
begin++;
ReadString(begin, end, stringLen);
end_ = begin;
} int BCodeString::ReadStringLen(
long long& begin,
long long& end)
{
std::vector<char> tmp;
if (isdigit(data_[begin]) == ) {
std::cerr << __FUNCTION__ << ". read num error!" << std::endl;
return ;
}
while (begin != end && isdigit(data_[begin])) {
tmp.push_back(data_[begin++]);
}
return atoi(&tmp[]);
} BCodeIntenger::BCodeIntenger(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeInt_(), BCode(BCODE_INTENGER_TYPE), data_(data)
{
begin_ = begin;
if (begin >= end || data_[begin] != 'i') {
std::cerr << __FUNCTION__ << ". intenger flag error!" << std::endl;
return;
}
++begin; //skip 'i' std::string intstr;
std::vector<char> tmp;
while (begin != end && data_[begin] != 'e' ) {
if (!isdigit(data_[begin])) {
std::cerr << __FUNCTION__ << ". get intenger error!" << std::endl;
return;
}
tmp.push_back(data_[begin++]);
}
end_ = begin;
++begin; //skip 'e'
if (begin > end) {
std::cerr << __FUNCTION__ << ". range error!" << std::endl;
return;
} bcodeInt_ = _atoi64(&tmp[]); #ifdef _DEBUG_PRINT
std::cout << __FUNCTION__ << ". BCodeIntenger = "
<< bcodeInt_ << std::endl;
#endif // DEBUG
} BCodeList::BCodeList(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeList_(), BCode(BCODE_LIST_TYPE),data_(data)
{
begin_ = begin;
if (begin >= end || data_[begin] != 'l') {
std::cerr << __FUNCTION__ << ". BCodeList error!" << std::endl;
return;
}
++begin;
#ifdef _DEBUG_PRINT
std::cout << "start List" << std::endl;
#endif // _DEBUG while (begin != end && data_[begin] != 'e') {
bcodeList_.push_back(GetBCodeObject(begin,end,data_));
}
end_ = begin;
if (begin >= end || data[end_] != 'e' ) {
std::cerr << __FUNCTION__ << ". BCodeList end error!" << std::endl;
return;
} ++begin;
#ifdef _DEBUG_PRINT
std::cout << "end List" << std::endl;
#endif // _DEBUG
} BCodeDictionary::BCodeDictionary(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeMap_(), BCode(BCODE_DICT_TYPE), data_(data)
{
begin_ = begin;
if (begin >= end || data_[begin] != 'd') {
std::cerr << __FUNCTION__ << ". range error!" << std::endl;
return;
}
++begin; //skip 'd'
#ifdef _DEBUG_PRINT
std::cout << "dict start " << std::endl;
#endif
while (begin != end && data[begin] != 'e') {
#ifdef _DEBUG_PRINT
std::cout << "key is ";
#endif
BCodeString key(begin, end,data);
std::shared_ptr<BCode> value = GetBCodeObject(begin,end,data);
if (value) {
bcodeMap_.insert(BCodemap::value_type(key.std_string(), value));
}
}
#ifdef _DEBUG_PRINT
std::cout << "dict end " << std::endl;
#endif
end_ = begin;
if (begin >= end || data[end_] != 'e') {
std::cerr << __FUNCTION__ << ". BCodeDictionary end error!" << std::endl;
return;
}
++begin; //skip 'e' return;
} std::shared_ptr<BCode> GetBCodeObject(long long& begin,
long long& end, const std::vector<char>& data) {
if (begin >= end || end > data.size()) {
std::cerr << __FUNCTION__ << ". Range error!" << std::endl;
return NULL;
} switch (data[begin]) {
case 'i':
return std::shared_ptr<BCode>(new BCodeIntenger(begin, end, data));
case 'l':
return std::make_shared<BCode>(BCodeList(begin, end, data));
case 'd':
return std::make_shared<BCode>(BCodeDictionary(begin,end,data));
default:
return std::make_shared<BCode>(BCodeString(begin, end, data));
} } NAMESPACEEND(DEF)
BCode.cpp
测试代码
#include <iostream>
#include "MetaFIleManager.h"
#include "BCode.h"
using namespace DEF;
void BCodetest() {
std::string s = "li1234e8:12345678l3:def3:abce4:1234i56789ee";
//std::string s = "8:123456783:def2:121:a";
std::vector<char> test(s.begin(), s.end());
long long size = test.size();
long long idx0 = 0;
//while (idx0 < size) {
std::shared_ptr<BCode> p = GetBCodeObject(idx0, size, test);
//}
std::cout << std::endl << std::endl;;
std::string s1 = "d4:key1d9:innerKey14:teste9:innerkey2li23456ei1234ei45678eee";
std::vector<char> test1(s1.begin(), s1.end());
long long size1 = test1.size();
long long idx1 = 0;
std::shared_ptr<BCode> p1 = GetBCodeObject(idx1, size1, test1);
}
int main()
{
BCodetest();
}
运行效果如图:

BCode解码练习的更多相关文章
- Huffman树及其编解码
Huffman树--编解码 介绍: Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于 ...
- linux字符串url编码与解码
编码的两种方式 echo '手机' | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g' echo '手机' |tr -d '\n' |od -An -tx ...
- URI编码解码和base64
概述 对于uri的编解码,在js中有3对函数,分别是escape/unescape,encodeURI/decodeURI,encodeURIComponent/decodeURIComponent. ...
- FFmpeg学习2:解码数据结构及函数总结
在上一篇文章中,对FFmpeg的视频解码过程做了一个总结.由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结. 本文的总结分为以下两个部分: 数据读取,主要关注在解码过程中所用到的FFm ...
- Unicode转义(\uXXXX)的编码和解码
在涉及Web前端开发时, 有时会遇到\uXXXX格式表示的字符, 其中XXXX是16进制数字的字符串表示形式, 在js中这个叫Unicode转义字符, 和\n \r同属于转义字符. 在其他语言中也有类 ...
- C# base 64图片编码解码
使用WinForm实现了图片base64编码解码的 效果图: 示例base 64编码字符串: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKD ...
- java编码原理,java编码和解码问题
java的编码方式原理 java的JVM的缺省编码方式由系统的“本地语言环境”设置确定,和操作系统的类型无关 . 在JAVA源文件-->JAVAC-->Class-->Java--& ...
- [LeetCode] Decode String 解码字符串
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...
- [LeetCode] Encode and Decode Strings 加码解码字符串
Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...
随机推荐
- Oracle从入门到精通----学习笔记
书名:<Oracle从入门到精通:视频实战版>秦靖.刘存勇等编著 第4章 SQL基础 1.SQL语言分类 数据定义语言 --- DDL,Data Definition Language 数 ...
- 转载:深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制
转载至 http://www.jasongj.com/zookeeper/fastleaderelection/: 原创文章,转载请务必将下面这段话置于文章开头处.本文转发自技术世界,原文链接 htt ...
- ubuntu安装后环境配置
首先实现能够连接外网,宿主机和虚拟机能ping通 进行smb的配置,能实现pytty的远程连接. 首先apt-get update 安装ssh apt-get install ssh 打开ssh服务 ...
- assert (boxes[:, 2] >= boxes[:, 0]).all()报错
根据报错信息,打印以下内容: 代码如下: for i in xrange(num_images): #print ('in append_flipped==================',self ...
- Java自学如何找工作
今天聊一下可能大多数人都关注的问题“自学Java如何找工作”那么首先你就要明确现在招聘Java开发的基本要求是什么?下面我们来看一下招聘网站上面的要求,在这里我只随便找了一个比较全面的要求,自己可以去 ...
- 40_redux_counter应用_redux完善版本
项目结构: 代码: import React from 'react'; import ReactDOM from 'react-dom'; import store from './redux/st ...
- Mysql分表:Merge
merge是Mysql最简单的一种分表,Mysql自带的一个分表功能,Merge表并不保存数据,Merge表和分表是对应映射关系.demo: 创建分表:CREATE TABLE `user1` ( ` ...
- 【400】numpy.pad 为数组加垫(迷宫类题目)
参考:Numpy学习——数组填充np.pad()函数的应用 举例说明: import numpy as np a = np.zeros((3, 4), dtype=int) a array([[0, ...
- GDI+_VB6_ARGB
在写一个用GDI+代替VB的Line函数的方法时,遇到了一个问题. GdipCreateSolidFill 参数 color [in]ARGB颜色,指定此实体画笔的初始颜色. brush [out]指 ...
- 一千行 MySQL 详细学习笔记
Windows服务 -- 启动MySQL net start mysql -- 创建Windows服务 sc create mysql binPath= mysqld_bin_path(注意:等号与值 ...