在python类中无痛苦地描述数据包的结构:不需要编写for循环或嵌套if条件。

bisturi的Python项目详细描述


bisturi是一个以不那么痛苦的方式解析二进制数据的库:不 需要编写“for”循环,而不是嵌套“if”条件这是一种 “你所看到的就是你所说的”解析器,它允许你 以声明方式打包和解包字节。

让我们通过例子来看看bisturi

这是典型的类型长度值包,我们可以如何描述 在比斯图里。

>>>frombisturi.packetimportPacket>>>frombisturi.fieldimportInt,Data>>>classTypeLengthValue(Packet):...type=Int(1)...length=Int(2)...value=Data(length)

>;从源代码很容易看出类型是1字节的整数 同时长度是2的整数。值是 长度字节的可变大小。

这就是你所需要的。bisturi的主要目标是 你要写简单的类,易于阅读和理解 一切都在分析幕后的细节。

在包定义之后,您可以在一次调用中解析任何字节字符串:

>>>raw=b'\t\x00\x04ABCD'>>>tlv=TypeLengthValue.unpack(raw)>>>tlv.type9>>>tlv.length4>>>tlv.value'ABCD'

你还可以解析(解包)一个字节字符串,你可以做相反的事情, 将数据包打包成字节字符串:

>>>tlv.pack()'\t\x00\x04ABCD'

int和data不是唯一可用的字段。下面是一个例子 如何描述位掩码

>>>frombisturi.fieldimportBits>>>classFrameControl(Packet):...length=Bits(6)...more_fragments=Bits(1)...fragment_offset=Bits(9)...data=Data(length)>>>raw=b'\x0c\x05abc'>>>fc=FrameControl.unpack(raw)>>>fc.length3>>>fc.more_fragments0>>>fc.fragment_offset5>>>fc.data'abc'

下面是如何描述一系列值(aka list)和 可选字段:

>>>classImage1D(Packet):...has_name=Bits(1)...count_numbers=Bits(7)......numbers=Int(1).repeated(count_numbers)...optional_name=Data(until_marker=b'\x00').when(has_name)>>>raw_without_name=b'\x03ABC'>>>image1d=Image1D.unpack(raw_without_name)>>>image1d.has_name0>>>image1d.count_numbers3>>>image1d.numbers[65,66,67]>>>image1d.optional_nameisNoneTrue>>>raw_with_name=b'\x83ABCsome null terminated name\x00garbage-garbage'>>>image1d=Image1D.unpack(raw_with_name)>>>image1d.has_name1>>>image1d.numbers[65,66,67]>>>image1d.optional_name'some null terminated name'

不仅可以使用字段的单个值定义大小或 其他字段的计数,但您可以描述任意表达式或 甚至对需要语句的更复杂的语句使用callable (在python中,它们不是表达式;请考虑“if”语句)。

我的意思是:

>>>classMatrix(Packet):...rows=Int(1)...columns=Int(1)......values=Int(1).repeated(rows*columns)# arithmetic operations>>>classAddress(Packet):...ip_address=Int(1).repeated(4)...domain_name=Data(until_marker=b'\x00').when((ip_address[:3]==[0,0,0])&...(ip_address[3]!=0))# subscript and comparisions>>>classToken(Packet):...size=Int(1)...data=Data(byte_count=lambdapkt,raw,offset,**k:pkt.sizeifpkt.size<8else8)...# ^-- an arbitrary callable is allowed too>>>raw_matrix=b'\x02\x03ABCDEF'>>>matrix_2x3=Matrix.unpack(raw_matrix)>>>cols=matrix_2x3.columns>>>matrix_2x3.values[0:cols]# first row[65,66,67]>>>matrix_2x3.values[cols:cols*2]# second row[68,69,70]>>>raw_resolved_address=b'\xc0\xa8\x00\x01'>>>resolved_address=Address.unpack(raw_resolved_address)>>>resolved_address.ip_address[192,168,0,1]>>>resolved_address.domain_nameisNoneTrue>>>raw_unresolved_address=b'\x00\x00\x00\x01example.com\x00'>>>unresolved_address=Address.unpack(raw_unresolved_address)>>>unresolved_address.ip_address[0,0,0,1]>>>unresolved_address.domain_name'example.com'>>>raw_small_token=b'\x01A'>>>small_token=Token.unpack(raw_small_token)>>>small_token.data'A'>>>raw_too_long_token=b'\xffABCD1234EFGH5678'>>>truncated_token=Token.unpack(raw_too_long_token)>>>truncated_token.data'ABCD1234'

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Kotlin应该为Java类中的合成属性进行反射   hadoop。pig脚本与java嵌入式pig:哪一个最快?   java要求用户在不关闭程序的情况下输入一个double而不是字符串   Raspberry PI和windows pc代码之间的java差异   使用maven的基于java Spring引导概要文件的WAR   Java中的内联数组定义   jsf如何在Tomcat上安装和使用CDI?   当数据来自mySQL时,在java的微调器中删除重复项   java如何定制Android ListView的每一行?   对于web应用程序,为什么java也被称为平台无关?   java如何获得排序hashmap中两个给定键之间的所有键值?   帮我把这个Java翻译成Scheme,让我脑子里的东西运转起来   java共享子域cookie   hibernate多Java列表删除   java队列可以用来交换链表的相邻节点吗?   java遇到错误:当我在安卓应用程序中单击主屏幕快捷方式时,找不到应用程序