近期搞项目中遇到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. radio和checkbox的js勾选使用

    Html: <table> <tr><th class="w1">党内职务</th><td colspan="3&q ...

  2. LeetCode 653. 两数之和 IV - 输入 BST(Two Sum IV - Input is a BST)

    653. 两数之和 IV - 输入 BST 653. Two Sum IV - Input is a BST 题目描述 给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定 ...

  3. LeetCode 1047. 删除字符串中的所有相邻重复项(Remove All Adjacent Duplicates In String)

    1047. 删除字符串中的所有相邻重复项 1047. Remove All Adjacent Duplicates In String 题目描述 LeetCode1047. Remove All Ad ...

  4. LeetCode 187. 重复的DNA序列(Repeated DNA Sequences)

    187. 重复的DNA序列 187. Repeated DNA Sequences 题目描述 All DNA is composed of a series of nucleotides abbrev ...

  5. SQL——LIKE操作符

    一.LIKE操作符的基本用法 LIKE操作符用于在WHERE子句中,搜索相似.类似的数据. LIKE操作符语法: SELECT 列名1,列名2... FROM 表名 WHERE 列名 LIKE xxx ...

  6. SQL server 常见错误--登录连接失败和附加数据库失败

    问题1:数据库软件登录连接不了,因为SQL server有部分服务没有开启,需要手动开启.       解决:计算机管理-->服务-->开启SQL server服务(具体那个自己慢慢试,就 ...

  7. scope:provided影响子依赖

    一.问题 在上一篇<SpringBoot项目启动不走内嵌容器>中发现,provided会影响子依赖. 标记为scope:provided的jar在编译和运行时有作用,表明了运行时depen ...

  8. Java对象深拷贝浅拷贝总结

    目录 深拷贝 1. 手动new 2. clone方法 3. java自带序列化 4. json序列化 性能测试 深拷贝总结 浅拷贝 1. spring BeanUtils(Apache BeanUti ...

  9. [LOJ6432] [PKUSC2018] 真实排名

    题目链接 LOJ:https://loj.ac/problem/6432 Solution 假设我们当前要算\(x\)的答案,分两种情况讨论: \(x\)没被翻倍,那么\([a_x/2,a_x]\)这 ...

  10. node-red 流程的导入导出

    流程的导入导出 流程的导出 选中所要导出的流程,点击右上角三条杠按钮 有两个选项,导出到剪贴板和库 1. 导出到剪贴板 导出到剪贴板可以复制,粘贴到任何地方 [{,,,,,,"wires&q ...