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 ...
随机推荐
- Maven打包报错:[WARNING] The POM for xxx is missing, no dependency inform
maven install 或 package 时 ,执行警告报错: [WARNING] The POM for com.xx-base:jar:1.0 is missing, no dependen ...
- Qt5 QtQuick系列----QtQuick的Secne Graph剖析(3)-- qml与OpenGl结合
我读的书愈多,就愈亲近世界,愈明了生活的意义,愈觉得生活的重要. -- 高尔基 需要先看:https://blog.csdn.net/qq_35865125/article/details/86485 ...
- hdu1016 Prime Ring Problem【素数环问题(经典dfs)】
Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- Sql CLR创建一个简单的表值函数
1.创建面目: 2. 添加函数代码: using System; using System.Data.Sql; using Microsoft.SqlServer.Server; using Syst ...
- 微软.NET CORE 3.0 预览版 7 发布:大幅减少 SDK 空间大小
据悉,这个预览版是 .Net Core 3 中重要的版本,可以视为原计划在 7 月发布的 RC 版本 (引自微软 .NET Core 首席 Program Manager Richard 先生原话), ...
- 关于WPF中的XAML
XAML全称extensible application markup language(可扩展性标记语言) 可扩展应用程序标记语言(XAML)是一种声明性语言.概括来说,就是为应用程序构建UI.目前 ...
- java之hibernate之helloworld
这篇文章,会一步一步的演示hibernate的使用. 目录结构如下: 1.新建java项目 2.增加一个lib文件夹,并把 hibernate必须的jar包 和 数据库驱动包 一起复制进去 然后把hi ...
- 【CH1809】匹配统计(KMP)
题目链接 摘自https://www.cnblogs.com/wyboooo/p/9829517.html 用KMP先求出以a[i]为结尾的前缀与b匹配的最长长度. 比如 f[i] = j,就表示a[ ...
- Qt QListWidget
以下代码是 List Widget 添加数据项的代码,一般放在构造函数即可. /*********************添加数据项*********************/ QIcon icon1 ...
- iOS 作为蓝牙外设广播信息
苹果蓝牙后台的限制,原本广播会有两个段分别是localName和serviceUUID这两块,但现在后台广播时,是不发送在这两段的 手机app可以作为一个蓝牙外设端来模拟外设硬件,但广播包里的数据只能 ...