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 ...
随机推荐
- 2522 和为K的倍数
2522 和为K的倍数 2 秒 262,144 KB 10 分 2 级题 小b喜欢和为K的倍数的序列. 现在有一个长度为n的序列A,请问A有多少个非空连续子序列是小b喜欢的. 收起 输入 第一 ...
- php把网络图片转Base64编码。
/** 把网络图片图片转成base64 * @param string $img 图片地址 * @return string */ /*网络图片转为base64编码*/ function imgtob ...
- c++堆和栈(转)
想要学好C++的C++堆栈,那么就要了解什么是C++堆栈,所为C++堆栈就是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除,分为堆和栈两部分. 在C++中,内存分 ...
- PHP+Ajax实现文件上传功能
前端显示界面: 1 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- python之路:模块初识
python王者开发之路:模块初识 模块初识我现在讲的确有点早.不过没关系,后面我会详细说模块. 模块,也就是库,是python三剑客之一.这三剑客,函数.库和类,都是由程序编写而成的.之所以我先说模 ...
- Java学习--变量
参考 http://www.runoob.com/java/java-variable-types.html java变量使用前 java中的所有变量在使用前必须声明并且初始化 类变量和实例变量会默 ...
- Android Studio添加aar依赖的两种方式
1 android{ repositories { flatDir { dirs 'libs' } } } dependencies { implementation fileTree(include ...
- Windows下pip 离线包安装
pip在线安装十分方便,有时候某些服务器并没有直接联网,需要下载好安装包上传到服务器上进行安装,不经常用,还是有点小麻烦的. 安装Python之后,将下载好的安装包包放在Python安装的根目录下使用 ...
- ISO 2501 quality model division 学习笔记
作为一个测试,学习质量模型,能够帮你 在测试设计的时候,从多个角度来思考测试用例的设计.而不仅仅是从 功能上, 同时 需要结合自己的产品,选择自己的侧重点,譬如我们公司的产品,安全性这一块 就比较小, ...
- CSS 图像高级 Css Sprites
上节课中我们学习了背景图像,这节课我们学习背景图像的高级知识,如Css Sprites,CSS 背景渐变等. Css Sprites Css Sprites,国内也叫CSS精灵.它的原理是将许多的小图 ...