0

我有以下简单的协议框架。为了测试,我一直假设一个固定的 CRC 字段,但现在我需要添加从帧中先前字节计算的实际 CRC。怎么做?也许通过嵌套结构?

MyFrame = Struct("MyFrame", 
                ULInt8("type"),
                ULInt8("IDMsg"),
                ULInt8("totalPackets"),
                ULInt8("numPacket"),
                ULInt8("day"),
                ULInt8("month"),
                ULInt8("year"),
                ULInt8("hour"),
                ULInt8("minute"),
                ULInt8("second"),
                ULInt16("length"),
                Bytes("payload", lambda ctx: (ctx.length - 14)),
                ULInt16("crc")
            )
4

2 回答 2

0

如果要检查 CRC 字段是否正确,请查看 Validator Adapter。用类似的东西覆盖_validate:

_validate(self, obj, context):
     return obj.crc == crc(context.type, context.idmsg, . . . )

其中 crc 是您的 CRC 函数,您使用上下文输入其余参数。

如果要向最终容器添加另一个字段,请使用 Value。

Value('calculated_crc', lambda ctx: crc(ctx.type, ctx.idmsg, . . . ))
于 2014-07-20T01:11:49.120 回答
0

可以使用隧道 API 对数据进行校验和(甚至压缩)。

https://construct.readthedocs.io/en/latest/tunneling.html#compression-and-checksuming

您的协议帧示例可以修改如下:

MyFrame = Struct(
        "body" / RawCopy(Struct(
            "type" / Int8ub,
            "IDMsg" / Int8ub,
            "totalPackets" / Int8ub,
            "numPacket" / Int8ub,
            "day" / Int8ub,
            "month" / Int8ub,
            "year" / Int8ub,
            "hour" / Int8ub,
            "minute" / Int8ub,
            "second" / Int8ub,
            "length" / Int16ul,
            "payload" / Bytes(this.length - 14),
        ),
        "crc" / Checksum(Int16ul,
            lambda data: crc_func(data),
            this.body.data)
)

此代码对构造 v2.10 有效。不幸的是,是的,您必须使用嵌套结构。

于 2022-01-12T11:13:35.047 回答