B編碼 Bencode 解析

2021-09-30 09:17:46 字數 4286 閱讀 9611

突然就想要解析了。。**寫的好亂。

想起來以前gif使用的lzw的編碼我還沒寫完解析呢。。近期大概也會寫的吧。。

解析了乙個7k的,在我這已經算小的種子檔案了。

└─dictionary

├─string:announce

├─string:

├─string:announce-list

├─list

├─string:created by

├─string:bitcomet/1.25

├─string:creation date

├─string:1301449953

├─string:encoding

├─string:utf-8

├─string:info

├─dictionary

├─string:nodes

└─list

第乙個list裡的內容是這樣的:

string:

string:

大概明白是怎麼一回事了。

雖然好像這東西跟json很像?沒注意過**有這個跟json的比較.

不過這東西有點太傻了。。它唯一的好處就是不像json那樣,解析起來傳統上需要分2部,詞法分析和語法分析。

bencode的解碼基本上完全可以把2步合起來。。

總之,種子檔案的根節點是乙個字典。

字典裡面的第乙個對映是由announce對映到乙個主tracker

然後是由announce-list對映到乙個列表,列表的內容是乙個由tracker伺服器組成的表。

字典裡面剩下的內容是created by資訊,creation date資訊,encoding資訊,info資訊。

前2個的內容都是字串,info資訊是乙個字典。

info字典的第乙個內容就是files。

files的內容是乙個列表,列表中每乙個元素都是字典。

這些字典中的每乙個當然都是對檔案的描述。

有以下這些描述:

ed2k,filehash,length,path,path.utf-8

由於根字典下有:

string:encoding

string:utf-8

所以這裡的path.utf-8和path的值是一樣的。

剛剛說到info字典的乙個物件,files列表

info字典還有以下物件:

name,name.utf-8,piece length,pieces

說起這個pieces物件我就覺得囧。

所以說,這b編碼的字串根本不是字串嘛。其實是位元組流吧。

像filehash這樣的東西都用字串表示,不覺得很奇怪嗎?理論上來說filehash應該是乙個整數。

當然,更不濟的情況下應該是乙個由整數組成的列表。

算了,以後我懂了,不能把b編碼中的字串型別看成是c字串,把它看做char型陣列還差不多。

而pieces。。哎。。

說完info字典,根字典下還有最後乙個物件是nodes列表。。這個列表的內容都是列表,裡面是由乙個其實標識著數字的字串和乙個整數0組成的。

你看,又把字串和整數混著用了。。

剛剛看到乙個好貼:

常見內容:

另外參考的是:

感謝這位博主。

**:

#include #include #include #include #ifndef max_path

#define max_path 260

#endif

namespace bcode;}

namespace bcode

int get_string_length(file *fp)

bf[bf_len] = 0;

fseek(fp,pos,seek_set);

return atoi(bf);

} int get_string(file *fp,char *buffer,int cch_buf)

assert(bf_len > 0);

assert(ch == ':' || (printf("ch=%d",ch),0));

bf[bf_len] = 0;

int str_len = atoi(bf);

assert(str_len > 0 && str_len < cch_buf);

int i;

for(i = 0; i < str_len && i < cch_buf - 1; ++i)

buffer[i] = 0;

return i;

} int get_integer(file *fp)

void get_encoded_string(char *buffer,int cchbuffer)

else

else if(buffer[buffer_ptr] == '>')

else if(buffer[buffer_ptr] == '&')

else if(buffer[buffer_ptr] == ' ')

else if(buffer[buffer_ptr] == '\n')

}buffer_ptr += 1;

} out_buffer[out_buffer_ptr] = 0;

strcpy(buffer,out_buffer);

delete out_buffer;

} cnode::cnode(file *fp, char type)

:value(null),parent(null),firstchild(null),nextsibling(null)

cnode::~cnode()

void cnode::setvalue(char *s)

char cnode::guess()

char cnode::guess(file *fp)

else if(ch == 'i' || ch == 'l' || ch == 'd')

return 0;

} void cnode::search()

else if(this ->type == 'i')

else if(this ->type == 'l')

else if(ch == 'i' || ch == 'l' || ch == 'd')

else

}} else if(this ->type == 'd')

}} void cnode::releasesubtree()

else

}this ->firstchild = null;

} cnode *cnode::createchild(char type)

else

n ->parent = this;

return n;

} void cnode::writefile(char *file_name)

void cnode::write(file *fp,int nlevel)

switch(this ->type)

}for(nspace = 0; nspace < nlevel; ++ nspace)

fputc(' ',fp);

fprintf(fp,"\n");

break;

case 'l':

fprintf(fp,"\n");

if(this ->firstchild)

}for(nspace = 0; nspace < nlevel; ++ nspace)

fputc(' ',fp);

fprintf(fp,"\n");

break;

case 's':

int len = 5 * ( 1 + strlen(this ->value));

char *t = new char[len];

strcpy(t,this ->value);

get_encoded_string(t,len);

fprintf(fp,"string:%s\n",t);

delete t;

break;

} }}int main(int argc, char *ar**)

bcode::cnode *root = null;

char type = root ->guess(fp);

root = new bcode::cnode(fp,type);

root ->search();

fclose(fp);

root ->writefile("out.xml");

delete root;

return 0;

}

Python 字元編碼 b

1.acsii碼以內的0 127,可以用字元本身表示位元組,也可用十六進製制表示,前面加b python console介面輸出bytes物件時,每讀乙個位元組就和ascii碼對比一下,如果符合ascii碼,該位元組就用ascii碼來表示 除去del等操作符外 否則用十六進製制 x 來表示 b x4...

B多元Huffman編碼問題

time limit 1000 ms memory limit 65536 kib submit statistic problem description 在乙個操場的四周擺放著n堆石子。現要將石子有次序地合併成一堆。規定每次至少選2 堆最多選k堆石子合併成新的一堆,合併的費用為新的一堆的石子數。...

ansi編碼轉換 8b 1b編碼是個什麼東東

使用序列比並行匯流排可以節省更多的佈線空間,晶元 電纜等的尺寸可以做得更小,同時傳輸速率更高。但是,在很多數字系統如cpu dsp fpga等內部,進行資料處理的最小單位都是byte,即8個bit,如何把乙個或多個byte的資料通過序列匯流排可靠地傳輸出去是需要對資料做些特殊處理的。並串轉換與串並轉...