近期搞项目中遇到Bencode解码的问题,就用Py写了个Bencode解码的代码。作为笔记保存参考。

BEncoding是BitTorrent用在传输数据结构的编码方式,这种编码方式支持四种类型的数据:string, int, Dictionary<string, object>, List<object>,各自的编码规则如下:

    • string类型的编码格式为[length]:[string]。以字符串的长度开头,加一个冒号,并以字符串内容结束。示例:"abc" => 3:abc
    • int类型的编码格式为i[int]e。以i开头,加上数字,以e结尾。 示例:123 => i123e
    • List<object>类型的编码格式为l[object]e。以l开头,加上列表中各个元素的编码(元素的类型同样为BEncoding支持的类型),以e结尾。 示例:List<"abc", 123> => l3:abci123ee
    • Dictionary<string, object>类型的编码格式为d[Key-Value Pair]e。以d开头,加上字典中每个键值对的编码,以e结尾。
# 解析List<object>类型,例:l3:abci123ee => List<"abc", 123>
def decode_list(str,p):
    l = len(str)
    # print(l)
    # print(p)
    list = []
    while p < l:
        if str[p + 1].isdigit():
            f_m = str.index(":",p + 1,l)
            f_n = int(str[p + 1:f_m])
            f_e = f_m + f_n
            data_str = str[f_m + 1:f_e + 1]
            list.append(data_str)
            p = f_e
        elif str[p + 1] == "i":
            end = str.index("e", p + 1, l)
            data_int = str[p + 2: int(end)]
            list.append(data_int)
            p = end
        elif str[p + 1] == "e":
            p = p + 2
            list.append("p")
            list.append(p)
            break
        elif str[p + 1] == "l":
            p = p + 1
    return list
 
# 解析Dictionary<string, object>类型,例:d4:name11:create chen3:agei23ee => Dictionary<{"name":"create chen"},{"age":23}>
def decode_dict(str,p):
    test = decode_list(str,p)
 
    data_seq = []
    data_val = []
 
    i = 0
    while i < len(test):
        data_seq.append(test[i])
        data_val.append(test[i + 1])
        i = i + 2
 
    data_dict = dict.fromkeys(data_seq)
 
    i = 0
    while i < len(test) / 2:
        data_dict[data_seq[i]] = data_val[i]
        i = i + 1
 
    return data_dict
 
data = "d4:name11:create chen3:agei23eel3:abci123eei23e3:age"
print(data)
# 定义全局指针,追踪所查位置
global p
l = len(data)
p = 0
while p < l:
    # 判断是否为dict型
    if data[p] == "d":
        data_dict = decode_dict(data,p)
        p = int(data_dict["p"])
        del data_dict["p"]
        print(data_dict)
        f = open("text.txt","a+")
        for k, v in data_dict.items():
            f.write(k + ":" + str(v))
            f.write("\n")
        f.close()
    # 判断是否为list型
    elif data[p] == "l":
        data_list = decode_list(data,p)
        p = int(data_list[-1])
        del data_list[-1]
        del data_list[-1]
        print(data_list)
        f = open("text.txt", "a+")
        for i in data_list:
            f.write(i)
            f.write("\n")
        f.close()
    # 判断是否为str型,解析
    elif data[p] == "i":
        f = data.index("e",p,l)
        data_int = data[p + 1:f]
        p = f + 1
        print(data_int)
        f = open("text.txt", "a+")
        f.write(data_int)
        f.write("\n")
        f.close()
    # 判断是否为int型,解析(为了方便,暂未将其结果转为int型,而是str型,例:“123”
    elif data[p].isdigit():
        f = data.index(":",p,l)
        print(data[f])
        data_str = data[f + 1:int(data[p:f]) + f + 1]
        print(data_str)
        p = int(data[p:f]) + f + 1
        f = open("text.txt", "a+")
        f.write(data_str)
        f.write("\n")
        f.close()
print("It's done")

  

python实现Bencode解码方法的更多相关文章

  1. python字符串操作实方法大合集

    python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下:   #1.去空格及特殊符号 s.st ...

  2. [LeetCode] 639. Decode Ways II 解码方法 II

    A message containing letters from A-Z is being encoded to numbers using the following mapping way: ' ...

  3. [LeetCode] Decode Ways 解码方法

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  4. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  5. Python执行系统命令的方法 os.system(),os.popen(),commands

    os.popen():用python执行shell的命令,并且返回了结果,括号中是写shell命令 Python执行系统命令的方法: https://my.oschina.net/renwofei42 ...

  6. python 调用 shell 命令方法

    python调用shell命令方法 1.os.system(cmd) 缺点:不能获取返回值 2.os.popen(cmd) 要得到命令的输出内容,只需再调用下read()或readlines()等   ...

  7. python 面向对象、特殊方法与多范式、对象的属性及与其他语言的差异

    1.python 面向对象 文章内容摘自:http://www.cnblogs.com/vamei/archive/2012/06/02/2532018.html   1.__init__() 创建对 ...

  8. python 字典内置方法get应用

    python字典内置方法get应用,如果我们需要获取字典值的话,我们有两种方法,一个是通过dict['key'],另外一个就是dict.get()方法. 今天给大家分享的就是字典的get()方法. 这 ...

  9. [转] python程序的调试方法

    qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...

随机推荐

  1. odoo 流水码 编码规则

    <?xml version="1.0" encoding="utf-8"?> <odoo> <data noupdate=&quo ...

  2. js图表库

    highcharts:https://www.hcharts.cn/ 商用收费,个人.公益免费,业界良心 百度家也有个echarts:http://echarts.baidu.com/ 免费,有许多小 ...

  3. 十、Spring的@Profile注解

    首先我们来看看spring官方文档对这个注解的解释: The @Profile annotation allows you to indicate that a component is eligib ...

  4. 【剑指offer】面试题 23. 链表中环的入口节点

    面试题 23. 链表中环的入口节点

  5. c++ 初始化

    1. 内置类型默认初始化 内置类型如果没有被显示初始化,则会被编译器默认初始化.初始化会根据①变量类型的不同②变量类型位置,来决定初始化之后的值.但是内置类型如果在函数体内部,则将不被初始化——也就是 ...

  6. easyui_datagrid实现导出Excel

    easyui_datagrid实现导出Excel 一.PHPExcel使用方法 先下载PHPExcel类库文件,并引入. 二.利用AJAX实现datagrid导出Excel 原理:前台通过AJAX调用 ...

  7. Numpy中矩阵和数组的区别

    矩阵(Matrix)和数组(Array)的区别主要有以下两点: 矩阵只能为2维的,而数组可以是任意维度的. 矩阵和数组在数学运算上会有不同的结构. 代码展示 1.矩阵的创建 采用mat函数创建矩阵 c ...

  8. Form' threw an exception of type 'System.InvalidOperationException'

    环境:VS2017 NetCore 2.2 Razor Layui 在处理异步请求是遇到"((Microsoft.AspNetCore.Http.Internal.DefaultHttpRe ...

  9. axios ios 微信浏览器session问题

    在ios系统下,微信浏览器使用axios 可能存在seesion不存在的问题,其原因是因为存在跨域 解决方案如下 1.修改域名为同一域名 2.后台允许跨域

  10. VsCode中好用的git源代码管理插件GitLens

    1.在插件tab搜索GitLens 2.安装成功后将光标移至代码行即会显示代码编写者 3.在VsCode左侧菜单栏,点击GitLens图标即可查看History,也可以查看全部的日志 4.查看上下pu ...