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 ...
随机推荐
- webpy学(ban)习(砖)记录
参考链接:http://blog.csdn.net/caleng/article/details/5712850 参考代码:http://files.cnblogs.com/files/tacyeh/ ...
- Spring MVC 集成Disconf
1.Disconf:Distributed Configuration Management Platform(分布式配置管理平台),专注于各种「分布式系统配置管理」的「通用组件」和「通用平台」, 提 ...
- 利用checkbox自带属性indeterminate构建含部分选中状态的树状结构
本来上个月就像发的,但是一直忙啊忙的也没时间整理,所以拖到了现在. 好吧上面这句就是废话,我就是感概下.下面是正文. 前段时间在弄一个轻量级的web项目,要构建一个树状结构目录,同时希望能把部分选中的 ...
- 基础Gan代码解析
initializer总结: #f.constant_initializer(value) 将变量初始化为给定的常量,初始化一切所提供的值. #tf.random_normal_initializer ...
- base编码解码
function b64EncodeUnicode(str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, func ...
- 使用samba 共享Linux文件到Windows
1.使用yum命令安装了samba服务 #yum install samba 2.配置/etc/samba/smb.conf文件,在最后一行添加下面一段配置: #vi /etc/samba/smb.c ...
- 使用 nodeJs 开发微信公众号(配置服务器)
流程如下: 1. 申请微信公众号:企业号.服务号.订阅号(前两个要钱) 2. 配置微信公众号后台 选择基本配置,获得 AppId 和 AppSecret ,点击服务器配置 URL:你服务器地址,不能是 ...
- Tomcat 启动时 SecureRandom 非常慢解决办法,亲测有效
1.找到jre—>lib—>security 2.找到 securerandom.source=file:/dev/random 替换成:securerandom.source= ...
- 【笔记】Python基础六:模块module介绍及常用模块
一,module模块和包的介绍 1,在Python中,一个.py文件就称之为一个模块(Module). 2,使用模块的好处? 最大的好处是大大提高了代码的可维护性 其次,编写代码不必从零开始,我们编写 ...
- BurpSuite抓HTTPS包
Burp Suite要抓HTTPS的包的话,是需要有Burp Suite的CA证书的 为什么要证书这里就不说了,下面是具体步骤 1.首先要把Burp Suite的CA证书下载到本地 Burp Suit ...