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 ...
随机推荐
- 001.[python学习]写在前面的
0.多动手写写也许你所说的问题就不是问题: 1.最好的帮助文档是dir和help,如下图: 2.如果为了快速完成任务可以选择IDE,否则尽量不要依赖它,因为它的智能导致自己的无能: 3.也许有其他语言 ...
- wdk1703+vs2015编译的诡异问题
最近将wdk升级到1703(10.0.15063.0)版本,编译一个新建的minifiter项目居然出现了失败 提示错误为 WindowsDriver.common.targets(460,5): e ...
- 关于前段JS代码报错问题的解决方法
最近接手别人的一个项目,项目导入到Myeclipse中,JS代码一直报错,说missing semicolon.该错误是Myeclipse在检查JS代码的过程出现的. 后来经过检查,发现JS代码本身没 ...
- rownum用法
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀. ...
- JavaScript学习-5——异步同步、回调函数
----------异步同步函数 ----------回调函数 一.异步同步函数 同步:发送一个请求,等待返回,然后再发送下一个请求 异步:发送一个请求,不等待返回,随时可以再发送下一个请求 同步可以 ...
- MPC学习笔记1:基于状态空间模型的预测控制(2)
基于估计的无约束预测控制 1.引言 基本上这两个部分都是在线性理论的框架下,利用状态空间法来建模.求解控制律.状态空间模型在理论分析上具有很强的优越性,但实际应用中能直接准确且经济地获取系统状态并不容 ...
- python运行时参数m的作用
不加m时,当前目录是py文件的所在目录 加m时,当前目录就是当前目录
- 逻辑读为何消耗CPU?
在数据库系统中,经常会看到这个说法:“逻辑读很消耗CPU”,然后开始把这句话当作一个定理来使用.但是为什么“同样是读,为什么逻辑读会使用那么多CPU?” 查了一些资料,配合自己的理解,有下面几点体会: ...
- week05 codelab01 Babel ES6 webpack Nodejsserver等
Babel 他出现的原因就是很多浏览器还未完全兼容ES6 需要将你写的ES6的内容转换成ES5让浏览器兼容运行 ES5和ES6相比出现很多新内容 比如拼接字符串 ES6可以` ` 里面如果引用变量就用 ...
- 如何利用webpack4.0搭建一个vue项目
作为一个初学者,记录自己踩过的坑是个好的习惯.我本身比较懒,这里刚好有时间把自己的搭建过程记录一下这里是参考文章 https://www.jianshu.com/p/1fc5b5151abf文章里 ...