用于构造结构化二进制数据包的模块。

Hydras的Python项目详细描述


九头蛇

Build Status

'hydras'是一个python库,允许开发人员根据简单的规则创建结构化的二进制数据, 有点类似于C对结构的处理。

示例

classHeader(Struct):Opcode=UInt8(4)# The `opcode`'s default value will now be `4`DataLength=UInt32()classDataPacket(Struct):# A nested structure. "DataLength = 128" sets the default DataLength value for `Header`s inside `DataPacket`sHeader=NestedStruct(Header(DataLength=128))# Creates an array of bytes with a length of 128 bytes.Payload=Array(length=128)# To override the constructor it must be able to override the default ctor (1 argument)def__init__(self,opcode=0):# Must call the base ctorsuper(DataPacket,self).__init__()self.Header.Opcode=opcodeif__name__=='__main__':packet=DataPacket()# After you create the object, you can ignore the formatting rules, and assign the data directly to the properties.packet.Header.Opcode=DATAPACKET_OPCODE# You can transform the object into a byte string using the `serialize` method.data_to_send=packet.serialize()# => b'\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...'some_socket.send(data_to_send)packet.Payload='\xFF'*128data_to_send=packet.serialize()# => b'\x04\x80\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF...'# . . .# You can parse raw byte strings into an object using the deserialize class method.received_data=some_socket.recv(len(packet))parsed_packet=DataPacket.deserialize(received_data)

您可以在examples目录中找到更多示例。

它是如何工作的?

在库的核心,有两种类型的对象:TypeFormatterStruct

TypeFormatter是一个格式化对象,可以解析和格式化指定类型的值。 Struct是一个结构对象,它允许您定义对象序列化的规则。

因此,开发人员可以使用以下符号声明类:

class<StructName>(Struct):<member_name>=<TypeClass>(<default_value>)

classMessage(Struct):TimeOfDay=UInt64()# This creates a UInt64 formatter.DataLength=UInt8(128)# A default value is optionalMessage().serialize()#=> b'\x00\x00\x00\x00\x00\x00\x00\x00\x80'

声明的数据成员实际上(由于python的语法)是静态的。 创建类对象时,构造函数(deep)将每个格式化程序default_value复制到同名的实例变量中, 因此,通过“诱使”用户认为不涉及格式化程序,可以实现一些透明度:

Class members:
  TimeOfDay:  UInt64 (default_value = 0)
  DataLength: UInt8  (default_value = 128)
Object members:
  TimeOfDay:  0
  DataLength: 128

序列化对象时,对象的数据与类的格式化程序交叉引用。 所有整数都是使用python的struct.pack函数在内部转换的。

验证器

可以将验证器对象分配给结构数据成员以定义验证规则。 当从二进制数据反序列化对象时,框架将验证这些值 使用用户定义的验证规则。

如果遇到无效值,将引发valueerror。

classMeIsValidated(Struct):member=Int8(0,validator=RangeValidator(-15,15))...MeIsValidated.deserialize('\x10')# => ValueError: The deserialized data is invalid.

为以下规则定义了一些内置验证器:

  • 范围验证器:范围检查
  • ExactValueValidator:精确值检查
  • BitSizeValidator:位长度检查
  • customvalidator:lambda验证(接收用户函数)
  • TrueValidator&FalseValidator:虚拟验证器(始终为真/始终为假)

可以通过子类化validator类来定义更多的验证器。

lambda验证器

用户可以使用lambda表达式(或任何函数)而不是验证程序对象作为验证规则。

classMeIsLambda(Struct):member=Int8(0,validator=lambdavalue:value%3==0)

挂钩

派生类可以实现钩子。

序列化前

此方法将在序列化即将发生之前调用。

note:如果HydraSettings.dry_run为真,则不会调用此方法, 或者用dry_run=True

调用serialize

序列化后

序列化发生后将调用此方法。

note:如果HydraSettings.dry_run为真,则不会调用此方法, 或者用dry_run=True

调用serialize

验证

在反序列化完成后调用。 如果返回Falsey值,deserialize将引发错误。

如果在自定义结构类中没有被用户重写,则方法 将使用类型格式化程序的验证程序进行验证。

当然,用户可以重写方法以添加自定义验证, 然后调用原始的validate方法。

note:如果将HydraSettings.validate设置为False,则不会引发错误。

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

推荐PyPI第三方库


热门话题
jsp上java调用bean方法   java如果一个autocloseable未存储在变量中,那么我是否必须尝试使用它?   安卓 java。lang.IllegalStateException:默认FirebaseApp未在此进程com中初始化。实例底部导航   java如何使用ObjectMapper处理多个参数?   java Intent在应用程序中不可用   具有相同DIV类的java自动组合框   java如何在Springboot中成功登录后限制POST Rest Api的公共访问   如何使用Java库(org.apache.hadoop.Hbase.client)从不同的网络连接Hbase?   java如何修复代码中的“找不到符号”?   属性中的java JAXWS命名空间,而不是前缀   java如何从AWS获取对本地主机客户端的响应?   java LibGDX初始化可绘制   爪哇包包装。。。或者类似的东西   java如果扩展了一个实现可序列化的类,为什么需要重新定义serialVersionUID?   zipfile Java WatchService等待文件完全写入   java Flamingo,如何在JCommandbuttons上放置Jtooltips   Java中斐波那契序列中的BufferedReader错误