python实现Bencode解码方法
近期搞项目中遇到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解码方法的更多相关文章
- python字符串操作实方法大合集
python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下: #1.去空格及特殊符号 s.st ...
- [LeetCode] 639. Decode Ways II 解码方法 II
A message containing letters from A-Z is being encoded to numbers using the following mapping way: ' ...
- [LeetCode] Decode Ways 解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- python 类属性与方法
Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...
- Python执行系统命令的方法 os.system(),os.popen(),commands
os.popen():用python执行shell的命令,并且返回了结果,括号中是写shell命令 Python执行系统命令的方法: https://my.oschina.net/renwofei42 ...
- python 调用 shell 命令方法
python调用shell命令方法 1.os.system(cmd) 缺点:不能获取返回值 2.os.popen(cmd) 要得到命令的输出内容,只需再调用下read()或readlines()等 ...
- python 面向对象、特殊方法与多范式、对象的属性及与其他语言的差异
1.python 面向对象 文章内容摘自:http://www.cnblogs.com/vamei/archive/2012/06/02/2532018.html 1.__init__() 创建对 ...
- python 字典内置方法get应用
python字典内置方法get应用,如果我们需要获取字典值的话,我们有两种方法,一个是通过dict['key'],另外一个就是dict.get()方法. 今天给大家分享的就是字典的get()方法. 这 ...
- [转] python程序的调试方法
qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...
随机推荐
- radio和checkbox的js勾选使用
Html: <table> <tr><th class="w1">党内职务</th><td colspan="3&q ...
- LeetCode 653. 两数之和 IV - 输入 BST(Two Sum IV - Input is a BST)
653. 两数之和 IV - 输入 BST 653. Two Sum IV - Input is a BST 题目描述 给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定 ...
- LeetCode 1047. 删除字符串中的所有相邻重复项(Remove All Adjacent Duplicates In String)
1047. 删除字符串中的所有相邻重复项 1047. Remove All Adjacent Duplicates In String 题目描述 LeetCode1047. Remove All Ad ...
- LeetCode 187. 重复的DNA序列(Repeated DNA Sequences)
187. 重复的DNA序列 187. Repeated DNA Sequences 题目描述 All DNA is composed of a series of nucleotides abbrev ...
- SQL——LIKE操作符
一.LIKE操作符的基本用法 LIKE操作符用于在WHERE子句中,搜索相似.类似的数据. LIKE操作符语法: SELECT 列名1,列名2... FROM 表名 WHERE 列名 LIKE xxx ...
- SQL server 常见错误--登录连接失败和附加数据库失败
问题1:数据库软件登录连接不了,因为SQL server有部分服务没有开启,需要手动开启. 解决:计算机管理-->服务-->开启SQL server服务(具体那个自己慢慢试,就 ...
- scope:provided影响子依赖
一.问题 在上一篇<SpringBoot项目启动不走内嵌容器>中发现,provided会影响子依赖. 标记为scope:provided的jar在编译和运行时有作用,表明了运行时depen ...
- Java对象深拷贝浅拷贝总结
目录 深拷贝 1. 手动new 2. clone方法 3. java自带序列化 4. json序列化 性能测试 深拷贝总结 浅拷贝 1. spring BeanUtils(Apache BeanUti ...
- [LOJ6432] [PKUSC2018] 真实排名
题目链接 LOJ:https://loj.ac/problem/6432 Solution 假设我们当前要算\(x\)的答案,分两种情况讨论: \(x\)没被翻倍,那么\([a_x/2,a_x]\)这 ...
- node-red 流程的导入导出
流程的导入导出 流程的导出 选中所要导出的流程,点击右上角三条杠按钮 有两个选项,导出到剪贴板和库 1. 导出到剪贴板 导出到剪贴板可以复制,粘贴到任何地方 [{,,,,,,"wires&q ...